Coder Social home page Coder Social logo

verilog-ethernet's Introduction

Verilog Ethernet Components Readme

Build Status

For more information and updates: http://alexforencich.com/wiki/en/verilog/ethernet/start

GitHub repository: https://github.com/alexforencich/verilog-ethernet

Introduction

Collection of Ethernet-related components for gigabit, 10G, and 25G packet processing (8 bit and 64 bit datapaths). Includes modules for handling Ethernet frames as well as IP, UDP, and ARP and the components for constructing a complete UDP/IP stack. Includes MAC modules for gigabit and 10G/25G, a 10G/25G PCS/PMA PHY module, and a 10G/25G combination MAC/PCS/PMA module. Includes various PTP related components for implementing systems that require precise time synchronization. Also includes full cocotb testbenches that utilize cocotbext-eth.

For IP and ARP support only, use ip_complete (1G) or ip_complete_64 (10G/25G).

For UDP, IP, and ARP support, use udp_complete (1G) or udp_complete_64 (10G/25G).

Top level gigabit and 10G/25G MAC modules are eth_mac_*, with various interfaces and with/without FIFOs. Top level 10G/25G PCS/PMA PHY module is eth_phy_10g. Top level 10G/25G MAC/PCS/PMA combination module is eth_mac_phy_10g.

PTP components include a configurable PTP clock (ptp_clock), a PTP clock CDC module (ptp_clock_cdc) for transferring PTP time across clock domains, and a configurable PTP period output module for precisely generating arbitrary frequencies from PTP time.

Example designs implementing a simple UDP echo server are included for the following boards:

  • Alpha Data ADM-PCIE-9V3 (Xilinx Virtex UltraScale+ XCVU3P)
  • BittWare 520N-MX (Intel Stratix 10 MX 1SM21CHU2F53E2VG)
  • Digilent Arty A7 (Xilinx Artix 7 XC7A35T)
  • Digilent Atlys (Xilinx Spartan 6 XC6SLX45)
  • Intel Cyclone 10 LP (Intel Cyclone 10 10CL025YU256I7G)
  • Terasic DE2-115 (Intel Cyclone IV E EP4CE115F29C7)
  • Terasic DE5-Net (Intel Stratix V 5SGXEA7N2F45C2)
  • Exablaze ExaNIC X10 (Xilinx Kintex UltraScale XCKU035)
  • Exablaze ExaNIC X25 (Xilinx Kintex UltraScale+ XCKU3P)
  • HiTech Global HTG-9200 (Xilinx Virtex UltraScale+ XCVU9P)
  • HiTech Global HTG-640 (HTG-V6HXT-100GIG-565) (Xilinx Virtex 6 XC6VHX565T)
  • Silicom fb2CG@KU15P (Xilinx Kintex UltraScale+ XCKU15P)
  • Xilinx KC705 (Xilinx Kintex 7 XC7K325T)
  • Xilinx ML605 (Xilinx Virtex 6 XC6VLX240T)
  • NetFPGA SUME (Xilinx Virtex 7 XC7V690T)
  • Digilent Nexys Video (Xilinx Artix 7 XC7A200T)
  • Intel Stratix 10 DX dev kit (Intel Stratix 10 DX 1SD280PT2F55E1VG)
  • Intel Stratix 10 MX dev kit (Intel Stratix 10 MX 1SM21CHU1F53E1VG)
  • Xilinx Alveo U50 (Xilinx Virtex UltraScale+ XCU50)
  • Xilinx Alveo U55C (Xilinx Virtex UltraScale+ XCU55C)
  • Xilinx Alveo U55N/Varium C1100 (Xilinx Virtex UltraScale+ XCU55N)
  • Xilinx Alveo U200 (Xilinx Virtex UltraScale+ XCU200)
  • Xilinx Alveo U250 (Xilinx Virtex UltraScale+ XCU250)
  • Xilinx Alveo U280 (Xilinx Virtex UltraScale+ XCU280)
  • Xilinx VCU108 (Xilinx Virtex UltraScale XCVU095)
  • Xilinx VCU118 (Xilinx Virtex UltraScale+ XCVU9P)
  • Xilinx VCU1525 (Xilinx Virtex UltraScale+ XCVU9P)
  • Xilinx ZCU102 (Xilinx Zynq UltraScale+ XCZU9EG)
  • Xilinx ZCU106 (Xilinx Zynq UltraScale+ XCZU7EV)
  • Arista 7132LB-48Y4C (Xilinx Virtex UltraScale+ XCVU9P)

Documentation

arp module

ARP handling logic with parametrizable retry timeout parameters and parametrizable datapath.

arp_cache module

Basic hash-based cache for ARP entries. Parametrizable depth.

arp_eth_rx module

ARP frame receiver with parametrizable datapath.

arp_eth_tx module

ARP frame transmitter with parametrizable datapath.

axis_eth_fcs module

Ethernet frame check sequence calculator.

axis_eth_fcs_64 module

Ethernet frame check sequence calculator with 64 bit datapath for 10G/25G Ethernet.

axis_eth_fcs_check module

Ethernet frame check sequence checker.

axis_eth_fcs_insert module

Ethernet frame check sequence inserter.

axis_gmii_rx module

AXI stream GMII/MII frame receiver with clock enable and MII select.

axis_gmii_tx module

AXI stream GMII/MII frame transmitter with clock enable and MII select.

axis_xgmii_rx_32 module

AXI stream XGMII frame receiver with 32 bit datapath.

axis_xgmii_rx_64 module

AXI stream XGMII frame receiver with 64 bit datapath.

axis_xgmii_tx_32 module

AXI stream XGMII frame transmitter with 32 bit datapath.

axis_xgmii_tx_64 module

AXI stream XGMII frame transmitter with 64 bit datapath.

eth_arb_mux module

Ethernet frame arbitrated multiplexer with parametrizable data width and port count. Supports priority and round-robin arbitration.

eth_axis_rx module

Ethernet frame receiver with parametrizable datapath.

eth_axis_tx module

Ethernet frame transmitter with parametrizable datapath.

eth_demux module

Ethernet frame demultiplexer with parametrizable data width and port count. Supports priority and round-robin arbitration.

eth_mac_1g module

Gigabit Ethernet MAC with GMII interface.

eth_mac_1g_fifo module

Gigabit Ethernet MAC with GMII interface and FIFOs.

eth_mac_1g_gmii module

Tri-mode Ethernet MAC with GMII/MII interface and automatic PHY rate adaptation logic.

eth_mac_1g_gmii_fifo module

Tri-mode Ethernet MAC with GMII/MII interface, FIFOs, and automatic PHY rate adaptation logic.

eth_mac_1g_rgmii module

Tri-mode Ethernet MAC with RGMII interface and automatic PHY rate adaptation logic.

eth_mac_1g_rgmii_fifo module

Tri-mode Ethernet MAC with RGMII interface, FIFOs, and automatic PHY rate adaptation logic.

eth_mac_10g module

10G/25G Ethernet MAC with XGMII interface. Datapath selectable between 32 and 64 bits.

eth_mac_10g_fifo module

10G/25G Ethernet MAC with XGMII interface and FIFOs. Datapath selectable between 32 and 64 bits.

eth_mac_mii module

Ethernet MAC with MII interface.

eth_mac_mii_fifo module

Ethernet MAC with MII interface and FIFOs.

eth_mac_phy_10g module

10G/25G Ethernet MAC/PHY combination module with SERDES interface.

eth_mac_phy_10g_fifo module

10G/25G Ethernet MAC/PHY combination module with SERDES interface and FIFOs.

eth_mac_phy_10g_rx module

10G/25G Ethernet MAC/PHY combination module with SERDES interface, RX path.

eth_mac_phy_10g_tx module

10G/25G Ethernet MAC/PHY combination module with SERDES interface, TX path.

eth_mux module

Ethernet frame multiplexer with parametrizable data width and port count. Supports priority and round-robin arbitration.

eth_phy_10g module

10G/25G Ethernet PCS/PMA PHY.

eth_phy_10g_rx module

10G/25G Ethernet PCS/PMA PHY receive-side logic.

eth_phy_10g_rx_ber_mon module

10G/25G Ethernet PCS/PMA PHY BER monitor.

eth_phy_10g_rx_frame_sync module

10G/25G Ethernet PCS/PMA PHY frame synchronizer.

eth_phy_10g_tx module

10G/25G Ethernet PCS/PMA PHY transmit-side logic.

gmii_phy_if module

GMII/MII PHY interface and clocking logic.

ip module

IPv4 block with 8 bit data width for gigabit Ethernet. Manages IPv4 packet transmission and reception. Interfaces with ARP module for MAC address lookup.

ip_64 module

IPv4 block with 64 bit data width for 10G/25G Ethernet. Manages IPv4 packet transmission and reception. Interfaces with ARP module for MAC address lookup.

ip_arb_mux module

IP frame arbitrated multiplexer with parametrizable data width and port count. Supports priority and round-robin arbitration.

ip_complete module

IPv4 module with ARP integration.

Top level for gigabit IP stack.

ip_complete_64 module

IPv4 module with ARP integration and 64 bit data width for 10G/25G Ethernet.

Top level for 10G/25G IP stack.

ip_demux module

IP frame demultiplexer with parametrizable data width and port count. Supports priority and round-robin arbitration.

ip_eth_rx module

IP frame receiver.

ip_eth_rx_64 module

IP frame receiver with 64 bit datapath for 10G/25G Ethernet.

ip_eth_tx module

IP frame transmitter.

ip_eth_tx_64 module

IP frame transmitter with 64 bit datapath for 10G/25G Ethernet.

ip_mux module

IP frame multiplexer with parametrizable data width and port count. Supports priority and round-robin arbitration.

lfsr module

Fully parametrizable combinatorial parallel LFSR/CRC module.

mii_phy_if module

MII PHY interface and clocking logic.

ptp_clock module

PTP clock module with PPS output. Generates both 64 bit and 96 bit timestamp formats. Fine frequency adjustment supported with configurable fractional nanoseconds field.

ptp_clock_cdc module

PTP clock CDC module with PPS output. Use this module to transfer and deskew a free-running PTP clock across clock domains. Supports both 64 and 96 bit timestamp formats.

ptp_td_leaf module

PTP time distribution leaf clock module. Accepts PTP time distribution messages from the ptp_td_phc module, and outputs both the 96-bit time-of-day timestamp and 64-bit relative timestamp in the destination clock domain, as well as both single-cycle and stretched PPS outputs. Also supports pipelining the serial data input, automatically compensating for the pipeline delay.

ptp_td_phc module

PTP time distribution master clock module. Generates PTP time distribution messages over a serial interface that can provide PTP time to one or more leaf clocks (ptp_td_leaf), as well as both single-cycle and stretched PPS outputs. The fractional nanoseconds portion is shared between the time-of-day and relative timestamps to support reconstruction of the 96-bit time-of-day timestamp from a truncated relative timestamp. The module supports coarse setting of both the ToD and relative timestamps as well as atomically applying offsets to the ToD and relative timestamps and the shared fractional nanoseconds.

ptp_ts_extract module

PTP timestamp extract module. Use this module to extract a PTP timestamp embedded in the tuser sideband signal of an AXI stream interface.

ptp_perout module

PTP period output module. Generates a pulse output, configurable in absolute start time, period, and width, based on PTP time from a PTP clock.

rgmii_phy_if module

RGMII PHY interface and clocking logic.

udp module

UDP block with 8 bit data width for gigabit Ethernet. Manages UDP packet transmission and reception.

udp_64 module

UDP block with 64 bit data width for 10G/25G Ethernet. Manages UDP packet transmission and reception.

udp_arb_mux module

UDP frame arbitrated multiplexer with parametrizable data width and port count. Supports priority and round-robin arbitration.

udp_checksum_gen module

UDP checksum generator module. Calculates UDP length, IP length, and UDP checksum fields.

udp_checksum_gen_64 module

UDP checksum generator module with 64 bit datapath. Calculates UDP length, IP length, and UDP checksum fields.

udp_complete module

UDP module with IPv4 and ARP integration.

Top level for gigabit UDP stack.

udp_complete_64 module

UDP module with IPv4 and ARP integration and 64 bit data width for 10G Ethernet.

Top level for 10G/25G UDP stack.

udp_demux module

UDP frame demultiplexer with parametrizable data width and port count. Supports priority and round-robin arbitration.

udp_ip_rx module

UDP frame receiver.

udp_ip_rx_64 module

UDP frame receiver with 64 bit datapath for 10G/25G Ethernet.

udp_ip_tx module

UDP frame transmitter.

udp_ip_tx_64 module

UDP frame transmitter with 64 bit datapath for 10G/25G Ethernet.

udp_mux module

UDP frame multiplexer with parametrizable data width and port count. Supports priority and round-robin arbitration.

xgmii_baser_dec_64 module

XGMII 10GBASE-R decoder for 10G PCS/PMA PHY.

xgmii_baser_enc_64 module

XGMII 10GBASE-R encoder for 10G PCS/PMA PHY.

xgmii_deinterleave module

XGMII de-interleaver for interfacing with PHY cores that interleave the control and data lines.

xgmii_interleave module

XGMII interleaver for interfacing with PHY cores that interleave the control and data lines.

Common signals

tdata   : Data (width generally DATA_WIDTH)
tkeep   : Data word valid (width generally KEEP_WIDTH, present on _64 modules)
tvalid  : Data valid
tready  : Sink ready
tlast   : End-of-frame
tuser   : Bad frame (valid with tlast & tvalid)

Source Files

rtl/arp.v                       : ARP handling logic
rtl/arp_cache.v                 : ARP LRU cache
rtl/arp_eth_rx.v                : ARP frame receiver
rtl/arp_eth_tx.v                : ARP frame transmitter
rtl/eth_arb_mux.py              : Ethernet frame arbitrated multiplexer generator
rtl/axis_eth_fcs.v              : Ethernet FCS calculator
rtl/axis_eth_fcs_64.v           : Ethernet FCS calculator (64 bit)
rtl/axis_eth_fcs_insert.v       : Ethernet FCS inserter
rtl/axis_eth_fcs_check.v        : Ethernet FCS checker
rtl/axis_gmii_rx.v              : AXI stream GMII/MII receiver
rtl/axis_gmii_tx.v              : AXI stream GMII/MII transmitter
rtl/axis_xgmii_rx_32.v          : AXI stream XGMII receiver (32 bit)
rtl/axis_xgmii_rx_64.v          : AXI stream XGMII receiver (64 bit)
rtl/axis_xgmii_tx_32.v          : AXI stream XGMII transmitter (32 bit)
rtl/axis_xgmii_tx_64.v          : AXI stream XGMII transmitter (64 bit)
rtl/eth_arb_mux.v               : Ethernet frame arbitrated multiplexer
rtl/eth_axis_rx.v               : Ethernet frame receiver
rtl/eth_axis_tx.v               : Ethernet frame transmitter
rtl/eth_demux.v                 : Ethernet frame demultiplexer
rtl/eth_mac_1g.v                : Gigabit Ethernet GMII MAC
rtl/eth_mac_1g_fifo.v           : Gigabit Ethernet GMII MAC with FIFO
rtl/eth_mac_1g_gmii.v           : Tri-mode Ethernet GMII/MII MAC
rtl/eth_mac_1g_gmii_fifo.v      : Tri-mode Ethernet GMII/MII MAC with FIFO
rtl/eth_mac_1g_rgmii.v          : Tri-mode Ethernet RGMII MAC
rtl/eth_mac_1g_rgmii_fifo.v     : Tri-mode Ethernet RGMII MAC with FIFO
rtl/eth_mac_10g.v               : 10G/25G Ethernet XGMII MAC
rtl/eth_mac_10g_fifo.v          : 10G/25G Ethernet XGMII MAC with FIFO
rtl/eth_mac_mii.v               : Ethernet MII MAC
rtl/eth_mac_mii_fifo.v          : Ethernet MII MAC with FIFO
rtl/eth_mac_phy_10g.v           : 10G/25G Ethernet XGMII MAC/PHY
rtl/eth_mac_phy_10g_fifo.v      : 10G/25G Ethernet XGMII MAC/PHY with FIFO
rtl/eth_mac_phy_10g_rx.v        : 10G/25G Ethernet XGMII MAC/PHY RX with FIFO
rtl/eth_mac_phy_10g_tx.v        : 10G/25G Ethernet XGMII MAC/PHY TX with FIFO
rtl/eth_mux.v                   : Ethernet frame multiplexer
rtl/gmii_phy_if.v               : GMII PHY interface
rtl/iddr.v                      : Generic DDR input register
rtl/ip.v                        : IPv4 block
rtl/ip_64.v                     : IPv4 block (64 bit)
rtl/ip_arb_mux.v                : IP frame arbitrated multiplexer
rtl/ip_complete.v               : IPv4 stack (IP-ARP integration)
rtl/ip_complete_64.v            : IPv4 stack (IP-ARP integration) (64 bit)
rtl/ip_demux.v                  : IP frame demultiplexer
rtl/ip_eth_rx.v                 : IPv4 frame receiver
rtl/ip_eth_rx_64.v              : IPv4 frame receiver (64 bit)
rtl/ip_eth_tx.v                 : IPv4 frame transmitter
rtl/ip_eth_tx_64.v              : IPv4 frame transmitter (64 bit)
rtl/ip_mux.v                    : IP frame multiplexer
rtl/lfsr.v                      : Generic LFSR/CRC module
rtl/mii_phy_if.v                : MII PHY interface
rtl/oddr.v                      : Generic DDR output register
rtl/ptp_clock.v                 : PTP clock
rtl/ptp_clock_cdc.v             : PTP clock CDC
rtl/ptp_td_leaf.v               : PTP time distribution leaf clock
rtl/ptp_td_phc.v                : PTP time distribution master clock
rtl/ptp_ts_extract.v            : PTP timestamp extract
rtl/ptp_perout.v                : PTP period out
rtl/rgmii_phy_if.v              : RGMII PHY interface
rtl/ssio_ddr_in.v               : Generic source synchronous IO DDR input module
rtl/ssio_ddr_in_diff.v          : Generic source synchronous IO DDR differential input module
rtl/ssio_ddr_out.v              : Generic source synchronous IO DDR output module
rtl/ssio_ddr_out_diff.v         : Generic source synchronous IO DDR differential output module
rtl/ssio_sdr_in.v               : Generic source synchronous IO SDR input module
rtl/ssio_sdr_in_diff.v          : Generic source synchronous IO SDR differential input module
rtl/ssio_sdr_out.v              : Generic source synchronous IO SDR output module
rtl/ssio_sdr_out_diff.v         : Generic source synchronous IO SDR differential output module
rtl/udp.v                       : UDP block
rtl/udp_64.v                    : UDP block (64 bit)
rtl/udp_arb_mux.v               : UDP frame arbitrated multiplexer
rtl/udp_checksum_gen.v          : UDP checksum generator
rtl/udp_checksum_gen_64.v       : UDP checksum generator (64 bit)
rtl/udp_complete.v              : UDP stack (IP-ARP-UDP)
rtl/udp_complete_64.v           : UDP stack (IP-ARP-UDP) (64 bit)
rtl/udp_demux.v                 : UDP frame demultiplexer
rtl/udp_ip_rx.v                 : UDP frame receiver
rtl/udp_ip_rx_64.v              : UDP frame receiver (64 bit)
rtl/udp_ip_tx.v                 : UDP frame transmitter
rtl/udp_ip_tx_64.v              : UDP frame transmitter (64 bit)
rtl/udp_mux.v                   : UDP frame multiplexer
rtl/xgmii_baser_dec_64.v        : XGMII 10GBASE-R decoder
rtl/xgmii_baser_enc_64.v        : XGMII 10GBASE-R encoder
rtl/xgmii_deinterleave.v        : XGMII data/control de-interleaver
rtl/xgmii_interleave.v          : XGMII data/control interleaver

AXI Stream Interface Example

transfer with header data

              __    __    __    __    __    __    __
clk        __/  \__/  \__/  \__/  \__/  \__/  \__/  \__
           ______________                   ___________
hdr_ready                \_________________/
                    _____ 
hdr_valid  ________/     \_____________________________
                    _____
hdr_data   XXXXXXXXX_HDR_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                    ___________ _____ _____
tdata      XXXXXXXXX_A0________X_A1__X_A2__XXXXXXXXXXXX
                    ___________ _____ _____
tkeep      XXXXXXXXX_K0________X_K1__X_K2__XXXXXXXXXXXX
                    _______________________
tvalid     ________/                       \___________
                          _________________
tready     ______________/                 \___________
                                      _____
tlast      __________________________/     \___________

tuser      ____________________________________________

two byte transfer with sink pause after each byte

          __    __    __    __    __    __    __    __    __
clk    __/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__
                _____ _________________
tdata  XXXXXXXXX_D0__X_D1______________XXXXXXXXXXXXXXXXXXXXXXXX
                _____ _________________
tkeep  XXXXXXXXX_K0__X_K1______________XXXXXXXXXXXXXXXXXXXXXXXX
                _______________________
tvalid ________/                       \_______________________
       ______________             _____             ___________
tready               \___________/     \___________/
                      _________________
tlast  ______________/                 \_______________________

tuser  ________________________________________________________

two back-to-back packets, no pauses

          __    __    __    __    __    __    __    __    __
clk    __/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__
                _____ _____ _____ _____ _____ _____
tdata  XXXXXXXXX_A0__X_A1__X_A2__X_B0__X_B1__X_B2__XXXXXXXXXXXX
                _____ _____ _____ _____ _____ _____
tkeep  XXXXXXXXX_K0__X_K1__X_K2__X_K0__X_K1__X_K2__XXXXXXXXXXXX
                ___________________________________
tvalid ________/                                   \___________
       ________________________________________________________
tready
                            _____             _____
tlast  ____________________/     \___________/     \___________

tuser  ________________________________________________________

bad frame

          __    __    __    __    __    __
clk    __/  \__/  \__/  \__/  \__/  \__/  \__
                _____ _____ _____
tdata  XXXXXXXXX_A0__X_A1__X_A2__XXXXXXXXXXXX
                _____ _____ _____
tkeep  XXXXXXXXX_K0__X_K1__X_K2__XXXXXXXXXXXX
                _________________
tvalid ________/                 \___________
       ______________________________________
tready
                            _____
tlast  ____________________/     \___________
                            _____
tuser  ____________________/     \___________

Testing

Running the included testbenches requires cocotb, cocotbext-axi, cocotbext-eth, and Icarus Verilog. The testbenches can be run with pytest directly (requires cocotb-test), pytest via tox, or via cocotb makefiles.

verilog-ethernet's People

Contributors

alexforencich avatar lomotos10 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

verilog-ethernet's Issues

UDP invalid payload length

It seems that the UDP payload length is miss handeled.

If I have short frame, the udp_payload contains the padding.

To fix that, i change the following line into the file udp_ip_rx.v, from:

word_count_next = m_udp_length_reg - 16'd8;

to

word_count_next = m_udp_length_reg;

Typo in eth_gth_phy_quad.v line 233

Discrepancy (likely typo) between Coregen IP instantiate in eth_gth_phy_quad.v line 233 in example/HXT100G/fpga/rtl/.

Component name as per .xco is ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper, while the substantiation refers to ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_QUAD.

Change instantiation to match .xco as a solution?

missing parts for PTP and 1g example design with PTP source

First of all thank you for your excellent work regarding the verilog ethernet and axi repos.
I am currently trying to understand and activate your PTP components and i am uncertain because i read in a different issue that PTP is not necessarily 100% complete. What's here exactly missing? And is there an example where PTP is activated and PTP source clock is connected?

I already found the three parameters in the eth_mac_phy_10g_fifo file to activate PTP for 10G design, it synthesize and generate+connect all PTP related components.
Is it possible to copy it simple to the 1G design with the 10G design as "template"? Or is it necessary to pay attention at some stages?
Thanks

Recursive call in priority encoder doesn't seem to work in Synplify

In priority_encoder.v, when WIDTH is greater than 2, I believe Synplify throws a warning and doesn't synthesize that section. In the ethernet stack, all of the WIDTHs (eth_arb_mux and ip_arb_mux) are equal to 2 so it didn't have any issues. However when using it standalone (axis_arb_mux), looks like that's causing some problems when WIDTH>2. Vivado seems to work fine. Anyone else seeing this issue?

eth_crc_8.v missing

There are many references to module eth_crc_8 (..64), but I can't find the corresponding source files in the repository? Did you remove them?

loopback

How to connect between two ports in a DE2-115 Board. send message from port and receive from another

respond to ARP through direct connection but doesn't respond through the LAN Switch

Hi.
I added your GMII & UDP stack like the KC705 example.

when I connecting the Ethernet cable from the FPGA to the PC, there is not a lot of traffic, {~1packet / 1sec on average},
I make ARP broadcast from my computer and the FPGA responding correctly and I can see the FPGA on the LAN (arp -a).

On the other hand, when I connect the FPGA to my LAN switch, {~20packets / 1sec on average}, and the PC also connected to this switch, once again I broadcast ARP requests through the LAN, I can see this request on the LAN using Wireshark, but the FPGA not responding to it.

Any idea why that might happen? Does the FPGA miss this request because of a heavy load of traffic on the cable? seems unreasonable, any idea what going on?
Edit:
I tried in the direct connection where is not a lot of traffic to send a fast stream of UDP packets.. and seems like the FPGA catch them all so the explanation of too much traffic on the cable seems more unreasonable now.

Edit2:
------------------------------

Edit3:
In both cases, I can see the transmit path logic ticking. When it is connected to the LAN and not responding to ARP request as I described my problem, in the FPGA logic I can see the MAC trying to respond:

sent_not_good

and it even seems like a good response because I compared it to the working case (connected directly from FPGA to PC with USB adapter {Ethernet->USB-C} in between):
sent_good

seems like the only difference is the different MAC Address between the cases (when connected through Switch the MAC it's trying to respond to is my PC MAC Address and in the working case it's responding to the adapter MAC Address.

Thanks!
(btw my solution to this issue: #47 was to pass the input clock in Lattice PLL and output 125MHz clock... I think it's a good enough solution for now no?)

VCU-118 10G and 25G Ethernet half expected data rate

I may be doing something dreadfully wrong but I'm getting about half the expected data rates for the 10G and 25G QSFP Ethernet examples. (its okay, even half rate is more than enough for my application!)

The example projects appear to use all the QSFP pins on both connectors; is it expecting to flow data through both connectors? (I only have one connected; could this explain me getting half the expected data rate?)

Problem with sythesizing - VCU108 - fpga_1g

Hi,

I am trying to implement the 1g version on the VCU108 evaluation board. I manually added all the files to the project as I am using Windows machine.

I added the files as per the make file which has links to all the files needed for fpga-1g version. ( Folder ..../fpga-1g/fpga)

When i try to synthesize i get the error saying that the get_property should have atleast one object and is referring to both the tcl scripts eth_mac_fifo and axis_async_fifo.

It looks the hardware is not being generated only. I am not sure about the problem. I am I missing anything. I am using Vivado version 2019.2

When I disable both the tcl scripts I am sucessfully able to generate the bit file but it doesn't work. The IP 192.168.1.128 is reachable but nothing is being echoed back.

Can you please help me understand what can be the issue.

Thanks,

Ramu

How to apply your project into ZC706?

Dear author:
First,thanks for your sharing the code,but now i am going apply it on ZC706.Of course i have found some data,then i find that ZC706 can only use the SFP.so i wonder if i can use your code or which part i can use.i am a beginning student,but i want to learn.so can you tell me how to put your code on the ZC706.Thank you very much.

Vivado block diagram, recursive priority encoder

I successfully built the example project for my board with Vivado, but now I need to integrate it with the rest of my system (Microblaze). Just like this issue here Vivado is complaining about the recursive definition of the priority encoder when trying to import the modules into the block diagram. From what I understand about this question I only need the eth_mac_1g_rgmii_fifo and the udp_complete (and the TCL files, I just copied all the ones used in the example project). So potentially I could just rewrite the module myself? I know back in Feb there was talk of doing so. Doesn't seem like it would be too terribly difficult, but I doubt my abilities when it comes to high speed stuff.

Block Diagram

Thank you so much for a great library.

I'm wondering if there already exists a block diagram for udp_complete or ip_complete. With all the muxing going on it can be hard to follow all the connections to understand what's going on.

Thanks in advance.

VCU118 25G ...payload_axis_tdata[] width

In example/VCU118/fpga_25g the rates (156.25 MHz) and widths (64 bits) of rx_udp_payload_axis_tdata and tx_udp_payload_axis_tdata appear to be sized for 10G and not 25G. I do see the GTY line rate is higher in the *.xci file.

PC Ethernet connection settings

I used KC705 Ethernet code to implement Ethernet on my custom Artix board. I remove button and uart interface of code, because i haven't them on my board.
I used ila to see output of phy_rxd when running on the board.

After programming and running, I set Ethernet cable with below code: (eth0 is board connection)
ifconfig enp7s0 192.168.1.128 netmask 255.255.255.0
and set configuration of ethernet connection to Automatic(DHCP)

but when i echo something through below terminal command:
netcat -u 192.168.1.128 1234
nothing coming on phy_rxd .

Is something wrong with my setting?

DE2115 TXD

Hi,

I'm running the ethernet code provided for DE2-115. I'm able to see data from AXI input, AXI output signals and rgmii_rxd till eth_mac_1g_rgmii_fifo.v but not rgmii_txd. Also ENET0_RX_DATA, ENET0_RX_DV but not ENET0_TX_DATA, ENET0_TX_EN. I cannot add signals from "oddr" to Signal Tap Logic Analyzer in Quartus. Can you help me out in finding the issue. TIA

make build error for VCU118 projects

When I try to run make on any of the VCU118 projects, I get the following error:

make[1]: Entering directory '<path>/verilog-ethernet/example/VCU118/fpga_25g/fpga'
make[1]: *** No rule to make target 'fpga.bit', needed by 'fpga'.  Stop.

I've added the following to my path:
C:\Xilinx\Vivado\2019.2\bin
C:\Xilinx\Vivado\2019.2\bin\unwrapped\win64.o
C:\Xilinx\Vivado\2019.2\scripts

Am I missing something in my path? Thanks!

udp_complete for tx only

Thanks for this IP!

However, I have a small issue. I'm trying to figure out exactly what signals are needed to produce just a single UDP TX packet, but I can't seem to produce anything else than ARP packets. I'm trying to use the test_udp_complete.py as a guide. I noticed that if I commented out all other test cases but testcase5(UDP TX), the test failed. It only works if I uncomment testcase2(IP TX). When testcase2 is commented out, it seems that I'm only creating an ARP packet (type= 0x0806) and not IPv4 (type = 0x0800). Another hint for what I'm doing wrong might be that udp_tx_busy goes high, and stays high forever.

What exactly is it that happens in testcase 2 that is required to create a UDP TX packet in testcase5?

Any help is greatly appreciated!

Arty test, can't see loopback message

Hello,

I am trying to test the ARTY board loopback test.
Firstly, ping is not supported?

I use โ€˜netcatโ€™ command you recommended at README.md.

After connection, I typed 1,2,3โ€ฆ8 number then I can see the LD2,3 ON and LD4,5,6,7 changing the same input number
But only 10 or 11 times working, then it has frozen and needs to hard reset.

Also, I typed string message, but I canโ€™t see the echo string.

Please advise what I missing?

Thanks,

AU50 and AU280 build error

Hello,

I am trying to build AU50& AU280 and found build error.

INFO: [IP_Flow 19-2313] Loaded Vivado IP repository '/opt/Xilinx/Vivado/2019.1/data/ip'.
WARNING: [IP_Flow 19-3664] IP 'gtwizard_ultrascale_0' generated file not found '/home/kha/fpga/verilog-ethernet/example/AU50/fpga_10g/fpga/fpga.srcs/sources_1/ip/gtwizard_ultrascale_0/gtwizard_ultrascale_0.dcp'. Please regenerate to continue.
WARNING: [IP_Flow 19-3664] IP 'gtwizard_ultrascale_0' generated file not found '/home/kha/fpga/verilog-ethernet/example/AU50/fpga_10g/fpga/fpga.srcs/sources_1/ip/gtwizard_ultrascale_0/gtwizard_ultrascale_0_stub.v'. Please regenerate to continue.
WARNING: [IP_Flow 19-3664] IP 'gtwizard_ultrascale_0' generated file not found '/home/kha/fpga/verilog-ethernet/example/AU50/fpga_10g/fpga/fpga.srcs/sources_1/ip/gtwizard_ultrascale_0/gtwizard_ultrascale_0_stub.vhdl'. Please regenerate to continue.
WARNING: [IP_Flow 19-3664] IP 'gtwizard_ultrascale_0' generated file not found '/home/kha/fpga/verilog-ethernet/example/AU50/fpga_10g/fpga/fpga.srcs/sources_1/ip/gtwizard_ultrascale_0/gtwizard_ultrascale_0_sim_netlist.v'. Please regenerate to continue.
WARNING: [IP_Flow 19-3664] IP 'gtwizard_ultrascale_0' generated file not found '/home/kha/fpga/verilog-ethernet/example/AU50/fpga_10g/fpga/fpga.srcs/sources_1/ip/gtwizard_ultrascale_0/gtwizard_ultrascale_0_sim_netlist.vhdl'. Please regenerate to continue.
# reset_run synth_1
# launch_runs synth_1
ERROR: [Common 17-70] Application Exception: Failed to launch run 'synth_1' due to failures in the following run(s):
gtwizard_ultrascale_0_synth_1
These failed run(s) need to be reset prior to launching 'synth_1' again.

INFO: [Common 17-206] Exiting Vivado at Fri Sep  4 19:46:42 2020...
../common/vivado.mk:95: recipe for target 'fpga.runs/synth_1/%.dcp' failed
make[1]: *** [fpga.runs/synth_1/%.dcp] Error 1
make[1]: Leaving directory '/home/kha/fpga/verilog-ethernet/example/AU50/fpga_10g/fpga'
Makefile:14: recipe for target 'fpga' failed
make: *** [fpga] Error 2

eth_mac_mii_fifo module not fully working for me

Hello. First of all, thanks for this great ethernet IP.

I'm trying to use this ethernet mac & UDP/IP stack for my project, my board is Lattice ECP3 Versa, Marvel 88E1111 PHY.
I took the Arty example as a reference for implementing the ethernet MII & UDP/IP interface to my FPGA.

I did as in the example and instantiated fpga_core module like this:

ethernet_core ethernet_inst (
    .clk		 (phy_clk125),
    .rst		 (rst),
	.led		 (led),
 
    .phy_rx_clk	 (phy_rx_clk),
    .phy_rxd	 (phy_rxd[3:0]),
    .phy_rx_dv	 (phy_rx_dv),
    .phy_rx_er	 (phy_rx_er),
    .phy_tx_clk	 (phy_tx_clk),
    .phy_txd	 (phy_txd[3:0]),
    .phy_tx_en	 (phy_tx_en),
    .phy_col	 (phy_col),
    .phy_crs	 (phy_crs),
    .phy_rst_n   (phy_rst_n)
);

I just made a few changes that don't make any difference like delete the UART signals & Switches I don't use.
In the example, you created the 125MHz clock from Xilinx PLL, in my case I used the Marvel PHY 125MHz clock,
from Marvel 88E1111 PHY datasheet:
image

Next, inside the fpga_core, where the eth_mac_mii_fifo module instantiated I make sure that the TARGET parameters is "GENERIC":

eth_mac_mii_fifo #(
    .TARGET("GENERIC"),
    .CLOCK_INPUT_STYLE("BUFR"),
    .ENABLE_PADDING(1),
    .MIN_FRAME_LENGTH(64),
    .TX_FIFO_DEPTH(4096),
    .TX_FRAME_FIFO(1),
    .RX_FIFO_DEPTH(4096),
    .RX_FRAME_FIFO(1)
)
eth_mac_inst (
    .rst(rst),
    .logic_clk(clk),
    .logic_rst(rst),

    .tx_axis_tdata(tx_axis_tdata),
    .tx_axis_tvalid(tx_axis_tvalid),
    .tx_axis_tready(tx_axis_tready),
    .tx_axis_tlast(tx_axis_tlast),
    .tx_axis_tuser(tx_axis_tuser),

    .rx_axis_tdata(rx_axis_tdata),
    .rx_axis_tvalid(rx_axis_tvalid),
    .rx_axis_tready(rx_axis_tready),
    .rx_axis_tlast(rx_axis_tlast),
    .rx_axis_tuser(rx_axis_tuser),

    .mii_rx_clk(phy_rx_clk),
    .mii_rxd(phy_rxd),
    .mii_rx_dv(phy_rx_dv),
    .mii_rx_er(phy_rx_er),
    .mii_tx_clk(phy_tx_clk),
    .mii_txd(phy_txd),
    .mii_tx_en(phy_tx_en),
    .mii_tx_er(),

    .tx_fifo_overflow(),
    .tx_fifo_bad_frame(),
    .tx_fifo_good_frame(),
    .rx_error_bad_frame(),
    .rx_error_bad_fcs(),
    .rx_fifo_overflow(),
    .rx_fifo_bad_frame(),
    .rx_fifo_good_frame(),

    .ifg_delay(12)
);
configured the following mac / IP address:
// Configuration
wire [47:0] local_mac   = 48'h00_01_02_03_04_05;
wire [31:0] local_ip    = {8'd192, 8'd168, 8'd33,  8'd69};
wire [31:0] gateway_ip  = {8'd192, 8'd168, 8'd33,  8'd1};
wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0};
...
..
.
wire match_cond = rx_udp_dest_port == 1234;

Everything else Is the same as in the example and rtl files.

In my computer I connected an ethernet cable from my PC straight to the FPGA, the ethernet cable configured as following:
image

  • I created a bit file and programmed my device.

  • run analyzer to debug the code
    image
    ...
    image

the data the FPGA catch from RJ-45 is exactly the same data that can be seen in Wireshark traffic:
image
image

  • great my FPGA catching all the ethernet packets and make some process in the mac interface to present them as bytes.

  • keep moving on with the ethernet packet, that data goes to the module: axis_async_fifo_adapter and stuck there:
    image

it tries to write the data into the FIFO, and even the address counter is counting as it should, but all the other counters in this block (axis_async_fifo) don't move, and the empty flag stays high.
I can't get anything in the output of the FIFO and therefore the data just stuck there and never come out of the mii block and doesnt come in the udp_complete block (because there is no output from eth_mac_mii_fifo module).
I tries also make ARP request and on the FPGA i catch this data coming, but same as always got stuck in the FIFO.

why does it happening? any Idea?
Thanks! Michael.

top level logic:

module top (
    // board clock&reset / leds&switches
    input               clk_board,      // 100MHz versa board clock    	
    input               reset_n,        // rst neg - push button       
    output	[7:0]  		led,            // led array                                           
    output  		    dp,             // 7-seg screen led                               
    input 	[7:0]    	sw,             // switches                                

    // Ethernet: 100BASE-T MII   
    input               phy_tx_clk,                                                                                    
    output [7:0]        phy_txd,                                                                                   
    output              phy_tx_en,                                 
                                                                              
    input               phy_rx_clk,                                                       
    input  [7:0]        phy_rxd,       
    input               phy_rx_dv,                
    input               phy_rx_er,  
	
    input               phy_col,                                                                                 
    input               phy_crs,  
    output              phy_mdc,                                                                       
    inout               phy_mdio,                                      
	
	input               phy_clk125,
    output              phy_rst_n
	);

// ------- rst_n & rst -------- //	
wire rst, rst_n;
reg [7:0] count; 
assign rst_n = (count > 8'b1111_1010) ? 1'b1 : 1'b0;
assign rst = !rst_n;
		
always @(posedge clk_100 or negedge reset_n) begin
	if (~reset_n)
		count = 8'b0000_0000;
	else if (count < 8'b1111_1101)
		count = count + 1;
end	

// --- logic clock heart beat --- //
reg [23:0] heartbeat_cntr;
assign dp = heartbeat_cntr[23];

always @ (posedge phy_clk125 or negedge rst_n) begin
	if (~rst_n)
		heartbeat_cntr <= 24'h00_0000;
	else
		heartbeat_cntr <= heartbeat_cntr + 1;
end


ethernet_core ethernet_inst (
    .clk		 (phy_clk125),
    .rst		 (rst),
	.led		 (led),
 
    .phy_rx_clk	 (phy_rx_clk),
    .phy_rxd	 (phy_rxd[3:0]),
    .phy_rx_dv	 (phy_rx_dv),
    .phy_rx_er	 (phy_rx_er),
    .phy_tx_clk	 (phy_tx_clk),
    .phy_txd	 (phy_txd[3:0]),
    .phy_tx_en	 (phy_tx_en),
    .phy_col	 (phy_col),
    .phy_crs	 (phy_crs),
    .phy_rst_n   (phy_rst_n)
);

assign phy_txd[7:4] = 4'b0;
assign phy_mdc		= 1'b0;
assign phy_mdio		= 1'b0;

endmodule

ethernet core top after little changes:

module ethernet_core (
    input  wire       clk,
    input  wire       rst,
    output wire [7:0] led,

    input  wire       phy_rx_clk,
    input  wire [3:0] phy_rxd,
    input  wire       phy_rx_dv,
    input  wire       phy_rx_er,
    input  wire       phy_tx_clk,
    output wire [3:0] phy_txd,
    output wire       phy_tx_en,
    input  wire       phy_col,
    input  wire       phy_crs,
    output wire       phy_rst_n
);

// AXI between MAC and Ethernet modules
wire [7:0] rx_axis_tdata;
wire rx_axis_tvalid;
wire rx_axis_tready;
wire rx_axis_tlast;
wire rx_axis_tuser;

wire [7:0] tx_axis_tdata;
wire tx_axis_tvalid;
wire tx_axis_tready;
wire tx_axis_tlast;
wire tx_axis_tuser;

// Ethernet frame between Ethernet modules and UDP stack
wire rx_eth_hdr_ready;
wire rx_eth_hdr_valid;
wire [47:0] rx_eth_dest_mac;
wire [47:0] rx_eth_src_mac;
wire [15:0] rx_eth_type;
wire [7:0] rx_eth_payload_axis_tdata;
wire rx_eth_payload_axis_tvalid;
wire rx_eth_payload_axis_tready;
wire rx_eth_payload_axis_tlast;
wire rx_eth_payload_axis_tuser;

wire tx_eth_hdr_ready;
wire tx_eth_hdr_valid;
wire [47:0] tx_eth_dest_mac;
wire [47:0] tx_eth_src_mac;
wire [15:0] tx_eth_type;
wire [7:0] tx_eth_payload_axis_tdata;
wire tx_eth_payload_axis_tvalid;
wire tx_eth_payload_axis_tready;
wire tx_eth_payload_axis_tlast;
wire tx_eth_payload_axis_tuser;

// IP frame connections
wire rx_ip_hdr_valid;
wire rx_ip_hdr_ready;
wire [47:0] rx_ip_eth_dest_mac;
wire [47:0] rx_ip_eth_src_mac;
wire [15:0] rx_ip_eth_type;
wire [3:0] rx_ip_version;
wire [3:0] rx_ip_ihl;
wire [5:0] rx_ip_dscp;
wire [1:0] rx_ip_ecn;
wire [15:0] rx_ip_length;
wire [15:0] rx_ip_identification;
wire [2:0] rx_ip_flags;
wire [12:0] rx_ip_fragment_offset;
wire [7:0] rx_ip_ttl;
wire [7:0] rx_ip_protocol;
wire [15:0] rx_ip_header_checksum;
wire [31:0] rx_ip_source_ip;
wire [31:0] rx_ip_dest_ip;
wire [7:0] rx_ip_payload_axis_tdata;
wire rx_ip_payload_axis_tvalid;
wire rx_ip_payload_axis_tready;
wire rx_ip_payload_axis_tlast;
wire rx_ip_payload_axis_tuser;

wire tx_ip_hdr_valid;
wire tx_ip_hdr_ready;
wire [5:0] tx_ip_dscp;
wire [1:0] tx_ip_ecn;
wire [15:0] tx_ip_length;
wire [7:0] tx_ip_ttl;
wire [7:0] tx_ip_protocol;
wire [31:0] tx_ip_source_ip;
wire [31:0] tx_ip_dest_ip;
wire [7:0] tx_ip_payload_axis_tdata;
wire tx_ip_payload_axis_tvalid;
wire tx_ip_payload_axis_tready;
wire tx_ip_payload_axis_tlast;
wire tx_ip_payload_axis_tuser;

// UDP frame connections
wire rx_udp_hdr_valid;
wire rx_udp_hdr_ready;
wire [47:0] rx_udp_eth_dest_mac;
wire [47:0] rx_udp_eth_src_mac;
wire [15:0] rx_udp_eth_type;
wire [3:0] rx_udp_ip_version;
wire [3:0] rx_udp_ip_ihl;
wire [5:0] rx_udp_ip_dscp;
wire [1:0] rx_udp_ip_ecn;
wire [15:0] rx_udp_ip_length;
wire [15:0] rx_udp_ip_identification;
wire [2:0] rx_udp_ip_flags;
wire [12:0] rx_udp_ip_fragment_offset;
wire [7:0] rx_udp_ip_ttl;
wire [7:0] rx_udp_ip_protocol;
wire [15:0] rx_udp_ip_header_checksum;
wire [31:0] rx_udp_ip_source_ip;
wire [31:0] rx_udp_ip_dest_ip;
wire [15:0] rx_udp_source_port;
wire [15:0] rx_udp_dest_port;
wire [15:0] rx_udp_length;
wire [15:0] rx_udp_checksum;
wire [7:0] rx_udp_payload_axis_tdata;
wire rx_udp_payload_axis_tvalid;
wire rx_udp_payload_axis_tready;
wire rx_udp_payload_axis_tlast;
wire rx_udp_payload_axis_tuser;

wire tx_udp_hdr_valid;
wire tx_udp_hdr_ready;
wire [5:0] tx_udp_ip_dscp;
wire [1:0] tx_udp_ip_ecn;
wire [7:0] tx_udp_ip_ttl;
wire [31:0] tx_udp_ip_source_ip;
wire [31:0] tx_udp_ip_dest_ip;
wire [15:0] tx_udp_source_port;
wire [15:0] tx_udp_dest_port;
wire [15:0] tx_udp_length;
wire [15:0] tx_udp_checksum;
wire [7:0] tx_udp_payload_axis_tdata;
wire tx_udp_payload_axis_tvalid;
wire tx_udp_payload_axis_tready;
wire tx_udp_payload_axis_tlast;
wire tx_udp_payload_axis_tuser;

wire [7:0] rx_fifo_udp_payload_axis_tdata;
wire rx_fifo_udp_payload_axis_tvalid;
wire rx_fifo_udp_payload_axis_tready;
wire rx_fifo_udp_payload_axis_tlast;
wire rx_fifo_udp_payload_axis_tuser;

wire [7:0] tx_fifo_udp_payload_axis_tdata;
wire tx_fifo_udp_payload_axis_tvalid;
wire tx_fifo_udp_payload_axis_tready;
wire tx_fifo_udp_payload_axis_tlast;
wire tx_fifo_udp_payload_axis_tuser;

// Configuration
wire [47:0] local_mac   = 48'h00_01_02_03_04_05;
wire [31:0] local_ip    = {8'd192, 8'd168, 8'd33,  8'd69};
wire [31:0] gateway_ip  = {8'd192, 8'd168, 8'd33,  8'd1};
wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0};

// IP ports not used
assign rx_ip_hdr_ready = 1;
assign rx_ip_payload_axis_tready = 1;

assign tx_ip_hdr_valid = 0;
assign tx_ip_dscp = 0;
assign tx_ip_ecn = 0;
assign tx_ip_length = 0;
assign tx_ip_ttl = 0;
assign tx_ip_protocol = 0;
assign tx_ip_source_ip = 0;
assign tx_ip_dest_ip = 0;
assign tx_ip_payload_axis_tdata = 0;
assign tx_ip_payload_axis_tvalid = 0;
assign tx_ip_payload_axis_tlast = 0;
assign tx_ip_payload_axis_tuser = 0;

// Loop back UDP
wire match_cond = rx_udp_dest_port == 1234;
wire no_match = !match_cond;

reg match_cond_reg = 0;
reg no_match_reg = 0;

always @(posedge clk) begin
    if (rst) begin
        match_cond_reg <= 0;
        no_match_reg <= 0;
    end else begin
        if (rx_udp_payload_axis_tvalid) begin
            if ((!match_cond_reg && !no_match_reg) ||
                (rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin
                match_cond_reg <= match_cond;
                no_match_reg <= no_match;
            end
        end else begin
            match_cond_reg <= 0;
            no_match_reg <= 0;
        end
    end
end

assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond;
assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match;
assign tx_udp_ip_dscp = 0;
assign tx_udp_ip_ecn = 0;
assign tx_udp_ip_ttl = 64;
assign tx_udp_ip_source_ip = local_ip;
assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip;
assign tx_udp_source_port = rx_udp_dest_port;
assign tx_udp_dest_port = rx_udp_source_port;
assign tx_udp_length = rx_udp_length;
assign tx_udp_checksum = 0;

assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata;
assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid;
assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready;
assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast;
assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser;

assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata;
assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg;
assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg;
assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast;
assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser;

// Place first payload byte onto LEDs
reg valid_last = 0;
reg [7:0] led_reg = 0;

always @(posedge clk) begin
    if (rst) begin
        led_reg <= 0;
    end else begin
        if (tx_udp_payload_axis_tvalid) begin
            if (!valid_last) begin
                led_reg <= tx_udp_payload_axis_tdata;
                valid_last <= 1'b1;
            end
            if (tx_udp_payload_axis_tlast) begin
                valid_last <= 1'b0;
            end
        end
    end
end


assign led = led_reg;
assign phy_rst_n = !rst;


eth_mac_mii_fifo #(
    .TARGET("GENERIC"),
    .CLOCK_INPUT_STYLE("BUFR"),
    .ENABLE_PADDING(1),
    .MIN_FRAME_LENGTH(64),
    .TX_FIFO_DEPTH(4096),
    .TX_FRAME_FIFO(1),
    .RX_FIFO_DEPTH(4096),
    .RX_FRAME_FIFO(1)
)
eth_mac_inst (
    .rst(rst),
    .logic_clk(clk),
    .logic_rst(rst),

    .tx_axis_tdata(tx_axis_tdata),
    .tx_axis_tvalid(tx_axis_tvalid),
    .tx_axis_tready(tx_axis_tready),
    .tx_axis_tlast(tx_axis_tlast),
    .tx_axis_tuser(tx_axis_tuser),

    .rx_axis_tdata(rx_axis_tdata),
    .rx_axis_tvalid(rx_axis_tvalid),
    .rx_axis_tready(rx_axis_tready),
    .rx_axis_tlast(rx_axis_tlast),
    .rx_axis_tuser(rx_axis_tuser),

    .mii_rx_clk(phy_rx_clk),
    .mii_rxd(phy_rxd),
    .mii_rx_dv(phy_rx_dv),
    .mii_rx_er(phy_rx_er),
    .mii_tx_clk(phy_tx_clk),
    .mii_txd(phy_txd),
    .mii_tx_en(phy_tx_en),
    .mii_tx_er(),

    .tx_fifo_overflow(),
    .tx_fifo_bad_frame(),
    .tx_fifo_good_frame(),
    .rx_error_bad_frame(),
    .rx_error_bad_fcs(),
    .rx_fifo_overflow(),
    .rx_fifo_bad_frame(),
    .rx_fifo_good_frame(),

    .ifg_delay(12)
);

eth_axis_rx
eth_axis_rx_inst (
    .clk(clk),
    .rst(rst),
    // AXI input
    .s_axis_tdata(rx_axis_tdata),
    .s_axis_tvalid(rx_axis_tvalid),
    .s_axis_tready(rx_axis_tready),
    .s_axis_tlast(rx_axis_tlast),
    .s_axis_tuser(rx_axis_tuser),
    // Ethernet frame output
    .m_eth_hdr_valid(rx_eth_hdr_valid),
    .m_eth_hdr_ready(rx_eth_hdr_ready),
    .m_eth_dest_mac(rx_eth_dest_mac),
    .m_eth_src_mac(rx_eth_src_mac),
    .m_eth_type(rx_eth_type),
    .m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata),
    .m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid),
    .m_eth_payload_axis_tready(rx_eth_payload_axis_tready),
    .m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast),
    .m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser),
    // Status signals
    .busy(),
    .error_header_early_termination()
);

eth_axis_tx
eth_axis_tx_inst (
    .clk(clk),
    .rst(rst),
    // Ethernet frame input
    .s_eth_hdr_valid(tx_eth_hdr_valid),
    .s_eth_hdr_ready(tx_eth_hdr_ready),
    .s_eth_dest_mac(tx_eth_dest_mac),
    .s_eth_src_mac(tx_eth_src_mac),
    .s_eth_type(tx_eth_type),
    .s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata),
    .s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid),
    .s_eth_payload_axis_tready(tx_eth_payload_axis_tready),
    .s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast),
    .s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser),
    // AXI output
    .m_axis_tdata(tx_axis_tdata),
    .m_axis_tvalid(tx_axis_tvalid),
    .m_axis_tready(tx_axis_tready),
    .m_axis_tlast(tx_axis_tlast),
    .m_axis_tuser(tx_axis_tuser),
    // Status signals
    .busy()
);

udp_complete
udp_complete_inst (
    .clk(clk),
    .rst(rst),
    // Ethernet frame input
    .s_eth_hdr_valid(rx_eth_hdr_valid),
    .s_eth_hdr_ready(rx_eth_hdr_ready),
    .s_eth_dest_mac(rx_eth_dest_mac),
    .s_eth_src_mac(rx_eth_src_mac),
    .s_eth_type(rx_eth_type),
    .s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata),
    .s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid),
    .s_eth_payload_axis_tready(rx_eth_payload_axis_tready),
    .s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast),
    .s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser),
    // Ethernet frame output
    .m_eth_hdr_valid(tx_eth_hdr_valid),
    .m_eth_hdr_ready(tx_eth_hdr_ready),
    .m_eth_dest_mac(tx_eth_dest_mac),
    .m_eth_src_mac(tx_eth_src_mac),
    .m_eth_type(tx_eth_type),
    .m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata),
    .m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid),
    .m_eth_payload_axis_tready(tx_eth_payload_axis_tready),
    .m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast),
    .m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser),
    // IP frame input
    .s_ip_hdr_valid(tx_ip_hdr_valid),
    .s_ip_hdr_ready(tx_ip_hdr_ready),
    .s_ip_dscp(tx_ip_dscp),
    .s_ip_ecn(tx_ip_ecn),
    .s_ip_length(tx_ip_length),
    .s_ip_ttl(tx_ip_ttl),
    .s_ip_protocol(tx_ip_protocol),
    .s_ip_source_ip(tx_ip_source_ip),
    .s_ip_dest_ip(tx_ip_dest_ip),
    .s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata),
    .s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid),
    .s_ip_payload_axis_tready(tx_ip_payload_axis_tready),
    .s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast),
    .s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser),
    // IP frame output
    .m_ip_hdr_valid(rx_ip_hdr_valid),
    .m_ip_hdr_ready(rx_ip_hdr_ready),
    .m_ip_eth_dest_mac(rx_ip_eth_dest_mac),
    .m_ip_eth_src_mac(rx_ip_eth_src_mac),
    .m_ip_eth_type(rx_ip_eth_type),
    .m_ip_version(rx_ip_version),
    .m_ip_ihl(rx_ip_ihl),
    .m_ip_dscp(rx_ip_dscp),
    .m_ip_ecn(rx_ip_ecn),
    .m_ip_length(rx_ip_length),
    .m_ip_identification(rx_ip_identification),
    .m_ip_flags(rx_ip_flags),
    .m_ip_fragment_offset(rx_ip_fragment_offset),
    .m_ip_ttl(rx_ip_ttl),
    .m_ip_protocol(rx_ip_protocol),
    .m_ip_header_checksum(rx_ip_header_checksum),
    .m_ip_source_ip(rx_ip_source_ip),
    .m_ip_dest_ip(rx_ip_dest_ip),
    .m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata),
    .m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid),
    .m_ip_payload_axis_tready(rx_ip_payload_axis_tready),
    .m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast),
    .m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser),
    // UDP frame input
    .s_udp_hdr_valid(tx_udp_hdr_valid),
    .s_udp_hdr_ready(tx_udp_hdr_ready),
    .s_udp_ip_dscp(tx_udp_ip_dscp),
    .s_udp_ip_ecn(tx_udp_ip_ecn),
    .s_udp_ip_ttl(tx_udp_ip_ttl),
    .s_udp_ip_source_ip(tx_udp_ip_source_ip),
    .s_udp_ip_dest_ip(tx_udp_ip_dest_ip),
    .s_udp_source_port(tx_udp_source_port),
    .s_udp_dest_port(tx_udp_dest_port),
    .s_udp_length(tx_udp_length),
    .s_udp_checksum(tx_udp_checksum),
    .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata),
    .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid),
    .s_udp_payload_axis_tready(tx_udp_payload_axis_tready),
    .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast),
    .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser),
    // UDP frame output
    .m_udp_hdr_valid(rx_udp_hdr_valid),
    .m_udp_hdr_ready(rx_udp_hdr_ready),
    .m_udp_eth_dest_mac(rx_udp_eth_dest_mac),
    .m_udp_eth_src_mac(rx_udp_eth_src_mac),
    .m_udp_eth_type(rx_udp_eth_type),
    .m_udp_ip_version(rx_udp_ip_version),
    .m_udp_ip_ihl(rx_udp_ip_ihl),
    .m_udp_ip_dscp(rx_udp_ip_dscp),
    .m_udp_ip_ecn(rx_udp_ip_ecn),
    .m_udp_ip_length(rx_udp_ip_length),
    .m_udp_ip_identification(rx_udp_ip_identification),
    .m_udp_ip_flags(rx_udp_ip_flags),
    .m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset),
    .m_udp_ip_ttl(rx_udp_ip_ttl),
    .m_udp_ip_protocol(rx_udp_ip_protocol),
    .m_udp_ip_header_checksum(rx_udp_ip_header_checksum),
    .m_udp_ip_source_ip(rx_udp_ip_source_ip),
    .m_udp_ip_dest_ip(rx_udp_ip_dest_ip),
    .m_udp_source_port(rx_udp_source_port),
    .m_udp_dest_port(rx_udp_dest_port),
    .m_udp_length(rx_udp_length),
    .m_udp_checksum(rx_udp_checksum),
    .m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata),
    .m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid),
    .m_udp_payload_axis_tready(rx_udp_payload_axis_tready),
    .m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast),
    .m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser),
    // Status signals
    .ip_rx_busy(),
    .ip_tx_busy(),
    .udp_rx_busy(),
    .udp_tx_busy(),
    .ip_rx_error_header_early_termination(),
    .ip_rx_error_payload_early_termination(),
    .ip_rx_error_invalid_header(),
    .ip_rx_error_invalid_checksum(),
    .ip_tx_error_payload_early_termination(),
    .ip_tx_error_arp_failed(),
    .udp_rx_error_header_early_termination(),
    .udp_rx_error_payload_early_termination(),
    .udp_tx_error_payload_early_termination(),
    // Configuration
    .local_mac(local_mac),
    .local_ip(local_ip),
    .gateway_ip(gateway_ip),
    .subnet_mask(subnet_mask),
    .clear_arp_cache(0)
);

axis_fifo #(
    .DEPTH(8192),
    .DATA_WIDTH(8),
    .KEEP_ENABLE(0),
    .ID_ENABLE(0),
    .DEST_ENABLE(0),
    .USER_ENABLE(1),
    .USER_WIDTH(1),
    .FRAME_FIFO(0)
)
udp_payload_fifo (
    .clk(clk),
    .rst(rst),

    // AXI input
    .s_axis_tdata(rx_fifo_udp_payload_axis_tdata),
    .s_axis_tkeep(0),
    .s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid),
    .s_axis_tready(rx_fifo_udp_payload_axis_tready),
    .s_axis_tlast(rx_fifo_udp_payload_axis_tlast),
    .s_axis_tid(0),
    .s_axis_tdest(0),
    .s_axis_tuser(rx_fifo_udp_payload_axis_tuser),

    // AXI output
    .m_axis_tdata(tx_fifo_udp_payload_axis_tdata),
    .m_axis_tkeep(),
    .m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid),
    .m_axis_tready(tx_fifo_udp_payload_axis_tready),
    .m_axis_tlast(tx_fifo_udp_payload_axis_tlast),
    .m_axis_tid(),
    .m_axis_tdest(),
    .m_axis_tuser(tx_fifo_udp_payload_axis_tuser),

    // Status
    .status_overflow(),
    .status_bad_frame(),
    .status_good_frame()
);

endmodule
	

Undriven PTP inputs when instancing 'eth_mac_1g'

First, thank you for sharing your valuable AXIS and Ethernet repositories.
I'm currently using your 'eth_mac_1g' MAC on a VCU118 platform, and noticed that you don't drive the 'tx_ptp_ts' and 'rx_ptp_ts' inputs when you instance this module in 'eth_max_1g_fifo' module.

I noticed this when simulating my design with your MAC and the 'gig_ethernet_pcs_pma'. I'm currently forming my own raw Ethernet frames and sending these directly via the AXIS interface into 'eth_mac_1g' (bypassing all of the UDP/IP/ARP stack modules and also using Xilinx AXIS data FIFO instead of your CDC FIFOs) . For some unknown reason, the PHY on the receive end of this link is reporting CRC errors. I do see that you do compute the CRC and transmit to the 'gig_ethernet_pcs_pma' block via the 'gmii_txd' and 'gmii_tx_en' signals, but for some reason, when the FCS field is examined on the the receive side of the link (via Wireshark), it shows the FCS bits all set to 1's. Not sure if this is related to the undriven PTP inputs (probably not), but I figured I'd let you know about this discrepancy.

Thank you

porting to a ZCU102 and ZCU111?

Hello,

I am curious how to make the 10 GbE core work on the ZCU102 and ZCU111.

The ZCU111 have these extra signals:

SFP_TX_FAULT
SFP_TX_DISABLE J
SFP_MOD_DETECT
SFP_RS0
SFP_RS1
SFP_LOS

While the ZCU102 only has:

SFP0_TX_P
SFP0_TX_N
SFP0_RX_P
SFP0_RX_N
SFP0_TX_DISABLE(1)

While you have these signals on the VCU118 example:
qsfp2_modsell
qsfp2_resetl
qsfp2_modprsl
qsfp2_intl
qsfp2_lpmode

Question is do I need the extra VCU118 and ZCU111 signals? Also, it looks like you are using 2 10 GbE on the VCU118 is that correct? Sorry I am trying to port this into those two boards and I don't have a VCU118 in hand. Also, can I use a 1000Base-T with this? Thanks.

subnet decision issue

if (((arp_request_ip ^ gateway_ip) & subnet_mask) == 0) begin
                // within subnet, look up IP directly
                // (no bits differ between request IP and gateway IP where subnet mask is set)
      // some logic here
end

Is the expression to decide whether within subnet correct? I am confused.

The sample udp loopback respond to other IP

All of the UDP loopback sample have a bug and can respond to an incorrect destination IP.

For example, if I send data to the IP 192.168.1.250:1234 and the packet is received by the card, the card respond.

To fix that, I change the check into the fle fpga.v from

wire match_cond = rx_udp_dest_port == 1234;

to

wire match_cond = (rx_udp_dest_port == 1234 && rx_udp_ip_dest_ip == local_ip);

Minor nits. Default state in mdio state case

Running the VCU118 10G example design with Vivado and linter. One nits highlighted is the case statement implementing the mdio command FSM engine starting at 1043 in fpga.v. That case statement end with:

            4'd12: begin
                // done
                state_reg <= 4'd12;
            end
        endcase

Which of course ensure that it stops when done. But since the state space is incomplete the toots gets annoyed. How abot simply adding a

default:
state_reg <= 4d0;

ENABLE_PADDING(0) leads to failure

I tested example based on ATLYS/fpga code. It works, but it add zero padding to the end of udp packet. I don't need it.

In order to disable unwanted padding, I set ENABLE_PADDING(0) for eth_mac_1g_gmii_fifo. Unfortunately it leads to complete fail. Loopback example don't works with ENABLE_PADDING(0) and stops to receive payload from incoming udp packets (first byte of the udp payload is not passed to the led display).

Please fix it.

Using 10GbE UDP for ZC706 board

Hi Alex,

Thank you for putting together this project. I'm interested in porting it over to the Xilinx ZC706 board. Are there issues you see with doing this? Anything I should watch out for?

Sorry if this is not the best way to reach you, I wasn't sure how else to message a user now that private messaging is gone from GitHub.

gig_ethernet_pcs_pma_0 IP on board VCU108 (1g example)

Hi Alex,
First of all, want to thank you for such an amazing project. I am new to FPGA development and currently using Vivado 2019.2 version with VCU108 board. I am trying the 1g example.

1st Attempt : Linux env. -->
I followed your instruction to the word and found the following issue
"WARNING: [Vivado 12-4802] The synthesis checkpoint for IP '../gig_ethernet_pcs_pma_0.xci' is not generated and IP is locked. An out-of-context (OOC) run will be created and/or launched, but synthesis may not be able to complete or could result in incorrect behavior."
I believe the IP is upgraded (found in the IP catalog) and not synthesizing correctly. This caused implementation to fail.

Question--> How can I upgrade the IP in makefile. Is there a way I can do it? I tried other forums, couldn't find it.

2nd Attempt : Windows env. -->
I manually pulled every code for the experiment, IP, .xdc constraints, .tcl constraints. Upgraded the IP to the newer version present in IP catalog (GUI has option to upgrade IP). This completed synthesis, implementation, generated bit-stream and programmed the device. But didn't see the result as expected in netcat. No returned characters after pressing enter.

Question --> Is there some files or process that I might be missing in windows env.?

Making of Example Vivado Project

Hi Alex,

Hope you are doing great!

When I trying to make the example Vivado Project under /example/VCU118/fpga_10g, I run into the following error message:

cd fpga && make
make[1] : Entering directory 'xxxx/example/VCU118/fpga_10g/fpga'
make[1] : *** NO rule to maek target 'fpga.bit', need by 'fpga'. Stop.
make[1]: Leaving directory 'xxxx/example/VCU118/fpga_10g/fpga'
Makefile: 14: recipe for target 'fpga' failed
make: *** [fpga] Error 2

I've already added the binary file path of Vivado 2019.1 to PATH.

I think this should be a simple fix. Could you give me a hint on what I might missing in my configuration?

Thank you!

eth_mac_1g_fifo rx bad bcs interrupt is not assigned correctly

Line 169 of eth_mac_1g_fifo shows that the rx_error_bad_frame_int is assigned to both bits of the rx_sync_reg_1 register. I believe that bit 1 of the register should be assigned to rx_error_bad_fcs_int instead. This is also the case in the eth_mac_1g_rgmii_fifo module.

Bypass Xilinx PCS?

for your 10G ethernet solution, do you implement your own PCS layer in the fabric, and bypass the PCS that is built-in to the Xilinx transceiver macro?

Use of tkeep in the middle of a packet for ignoring bytes

Hi Alex,

Sorry for all the questions today. I have a small issue with using tkeep with eth_mac_10g_fifo. It seems like tkeep is not really a byte qualifier if it is used somewhere in the stream before tlast. It will only remove the last bytes in the stream.

For instance, this is an input:
image

The bytes that are in the position of the unasserted tkeep will be kept in the resulting xgmii output. However, the last four bytes of the stream are dropped, even though tkeep is asserted for all of them. This issue seems to originate from axis_xgmii_tx_64.v, where non tkeep bytes are really only dropped if they are in the last window.

My question is this: is this intended behavior and do the IP in general require that a complete stream with no gaps are delivered?

Cheers,
Ola

AXI config example

Hi,
do you have an example where the AXIS module "axis_registers.v" or AXI modules "axi_register_wd/rd.v" are used for configuring the ETH MAC?

thanks in advance
BR

make error at Cygwin64

Hello,

I am trying to build an example project, but I found it to make an error.
My setup is Vivado 2018.2 and any comment to make a bitstream file?

kha@kha-PC /cygdrive/c/home/test/verilog-ethernet/example/Arty/fpga
$ make
cd fpga && make
make[1]: Entering directory '/cygdrive/c/home/test/verilog-ethernet/example/Arty/fpga/fpga'
rm -rf defines.v
touch defines.v
for x in ; do echo '`define' $x >> defines.v; done
echo "create_project -force -part xc7a35t-csg324-1 fpga" > create_project.tcl
echo "add_files -fileset sources_1 defines.v" >> create_project.tcl
for x in  ../rtl/fpga.v  ../rtl/fpga_core.v  ../rtl/debounce_switch.v  ../rtl/sync_signal.v  ../lib/eth/rtl/ssio_sdr_in.v  ../lib/eth/rtl/mii_phy_if.v  ../lib/eth/rtl/eth_mac_mii_fifo.v  ../lib/eth/rtl/eth_mac_mii.v  ../lib/eth/rtl/eth_mac_1g.v  ../lib/eth/rtl/axis_gmii_rx.v  ../lib/eth/rtl/axis_gmii_tx.v  ../lib/eth/rtl/lfsr.v  ../lib/eth/rtl/eth_axis_rx.v  ../lib/eth/rtl/eth_axis_tx.v  ../lib/eth/rtl/udp_complete.v  ../lib/eth/rtl/udp_checksum_gen.v  ../lib/eth/rtl/udp.v  ../lib/eth/rtl/udp_ip_rx.v  ../lib/eth/rtl/udp_ip_tx.v  ../lib/eth/rtl/ip_complete.v  ../lib/eth/rtl/ip.v  ../lib/eth/rtl/ip_eth_rx.v  ../lib/eth/rtl/ip_eth_tx.v  ../lib/eth/rtl/ip_arb_mux.v  ../lib/eth/rtl/arp.v  ../lib/eth/rtl/arp_cache.v  ../lib/eth/rtl/arp_eth_rx.v  ../lib/eth/rtl/arp_eth_tx.v  ../lib/eth/rtl/eth_arb_mux.v  ../lib/eth/lib/axis/rtl/arbiter.v  ../lib/eth/lib/axis/rtl/priority_encoder.v  ../lib/eth/lib/axis/rtl/axis_fifo.v  ../lib/eth/lib/axis/rtl/axis_async_fifo.v  ../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v  ../lib/eth/lib/axis/rtl/sync_reset.v; do echo "add_files -fileset sources_1 $x" >> create_project.tcl; done
for x in  ../fpga.xdc  ../lib/eth/syn/mii_phy_if.tcl  ../lib/eth/syn/eth_mac_fifo.tcl  ../lib/eth/lib/axis/syn/axis_async_fifo.tcl  ../lib/eth/lib/axis/syn/sync_reset.tcl; do echo "add_files -fileset constrs_1 $x" >> create_project.tcl; done
for x in ; do echo "import_ip $x" >> create_project.tcl; done
for x in ; do echo "source $x" >> create_project.tcl; done
echo "exit" >> create_project.tcl
vivado -nojournal -nolog -mode batch -source create_project.tcl

****** Vivado v2018.2.2 (64-bit)
  **** SW Build 2348494 on Mon Oct  1 18:25:44 MDT 2018
  **** IP Build 2318053 on Mon Oct  1 21:44:26 MDT 2018
    ** Copyright 1986-2018 Xilinx, Inc. All Rights Reserved.

source create_project.tcl
# create_project -force -part xc7a35t-csg324-1 fpga
# add_files -fileset sources_1 defines.v
# add_files -fileset sources_1 ../rtl/fpga.v
# add_files -fileset sources_1 ../rtl/fpga_core.v
# add_files -fileset sources_1 ../rtl/debounce_switch.v
# add_files -fileset sources_1 ../rtl/sync_signal.v
# add_files -fileset sources_1 ../lib/eth/rtl/ssio_sdr_in.v
ERROR: [Vivado 12-172] File or Directory '../lib/eth/rtl/ssio_sdr_in.v' does not exist
INFO: [Common 17-206] Exiting Vivado at Sat Aug 15 01:00:50 2020...
make[1]: *** [../common/vivado.mk:91: fpga.xpr] Error 1
make[1]: Leaving directory '/cygdrive/c/

axis_eth_fcs modules example

is there any example where your "axis_eth_fcs.v" / "axis_eth_fcs_check.v" modules are used?
or a description where and how to use them?

currently if I use the "axis_eth_fcs_check.v" module within the "eth_mac_1g_rgmii", the loopback isn't working simultaneously

thanks in advance,
BR

First byte of Ethernet preamble being replaced by XGMII start byte

Looking at test_axis_xgmii_rx_64.py, and testing axis_xgmii_rx_64.v it seems that current behavior ignores the first 8 XGMII bytes (including the start byte 0xFB). However, I'd expect it to ignore the first 9 XGMII bytes (including the start byte 0xFB) since the ethernet preamble + start of frame delimiter is 8 bytes.
Additionally, in xgmii_ep.py (which is used to test the XGMII Rx) the first byte is replaced by the XGMII start byte. That is, one of the preamble 0x55 bytes isn't sent through the XGMII.

dl[0] = XGMII_START
cl[0] = 1

I added a print out for d and c in xgmii_ep.py when running test_axis_xgmii_rx_64.py and got what's below. You can see 0x55 is only repeated 6 times instead of 7.

d is d5555555555555fb
c is 1

support 40G

Hello, may I ask you a question? 40g is composed of four 10g channels. Referring to 802.3, we know that each channel adopts 64b / 66b coding standard. The axis stream output from Xilinx's MAC / PHY IP core is 256 bit wide. Where is the data merging of the four channels completed? Is it at the interface between the physical layer and the MAC layer

Unconnected clear_cache in arp_cache.v

Hi Alex,

Once again, thanks again for all your hard work. I've started to make out how to use most of your stuff now. However, the clear_cache wire on the arp_cache.v module seems to be unconnected. Any plans for adding some clear functionality in the near future?

Ola

Problems trying to combine GMII MAC Module with Xilinx PCS/PMA IP

Hello Alex, thanks for this amazing repository.

I'm having some troubles trying to connect your modules with the PCS/PMA IP. I started from the VCU108 example (which is also using the IP but with a LVDS transceiver) and made some changes. I'm using a device specific transceiver for 1G 1000BASE-X, so I changed the IP accordingly. I also changed to the eth_mac_1g_gmii_fifo module in the fpga_core file. I'm pretty sure that the PCS/PMA IP is well configured by checking at the last bit in the pcs_pma_status_vector. However, I cannot receive any packets from the FPGA.

fpga_core
pcs_pma
eth_mac_gmii

I am not sure what I'm doing wrong.

Any documents on how to use UDP stack?

Thanks for sharing this amazing library, this pretty much has everything I need.
I consider myself a beginner in HDL programming, and I find it very hard to use this library.
I need to implement a 1G UDP on zedboard (which has a 1g Ethernet FMC card) and I was trying to mimic the project style you have in your examples folder but I wasn't sure how to compile the project or where to make modifications. Your make files don't seem to be a gcc make.
would you be able to give some advice on how to use this library,

RX_DROP_BAD_FRAME in eth_mac_1g_fifo.v

RX_DROP_BAD_FRAME in eth_mac_1g_fifo.v is not used.

rx_fifo parameters in eth_mac_1g_fifo.v are assigned TX_FRAME_FIFO, TX_DROP_BAD_FRAME and TX_DROP_WHEN_FULL. I think they should be replaced with RX_... parameters. It looks like copy-paste error.

axis_xgmii_tx_32 state_reg not big enough

https://github.com/alexforencich/verilog-ethernet/blob/e9949f57a934071bf7da30445b88808e7fdd7124/rtl/axis_xgmii_tx_32.v

The state variables (such as STATE_WAIT_END) use 4 bits but the state variable state_reg uses 3.

localparam [3:0]
    STATE_IDLE = 4'd0,
    STATE_PREAMBLE = 4'd1,
    STATE_PAYLOAD = 4'd2,
    STATE_PAD = 4'd3,
    STATE_FCS_1 = 4'd4,
    STATE_FCS_2 = 4'd5,
    STATE_FCS_3 = 4'd6,
    STATE_IFG = 4'd7,
    STATE_WAIT_END = 4'd8;

reg [2:0] state_reg = STATE_IDLE, state_next;

so when in the code we have

state_next = STATE_WAIT_END

It's probably going to go to overflow and go to STATE_IDLE.

Unable to connect MII Ethernet interface with 1G/100M/10M switch

Hi, first of all, thanks for this great ethernet interface.
I added the MII interface as shown in the Arty example to my FPGA (I'm using Lattice ECP3 Dev Board with Marvel PHY 88e1111).
Although my PHY/Cables and Switches support 1G (GMII) I prefer to work with MII because some of my equipment doesn't support 1G.

The ethernet interface is working when I connect the FPGA through a switch that supports 10/100 only.
If I connect the FPGA through a switch that supports 10/100/1G I getting 8bit of packets to my FPGA (I connected all the 8bits to the FPGA so I can see what happens although I need to use only the 4 LSB in the MII interface), and the MII interface doesn't do anything with this data (I anyway connecting 4LSB to the ethernet core).

Case 1: 10/100 Switch -> MII Interface
image
image
as can be seen in this case the FPGA receives only 4bits and the MAC successfully processing this data.

--

Case 2: 10/100/1G Switch -> MII Interface
image
image
as can be seen in this case the FPGA receives 8bits and the MAC doesn't do anything with the data.


My question is how I can adjust the MII ethernet interface to work with 10/100/1G switches and cables?
the interface doesn't need to notify the LAN about that he can receive only 10/100 data packets?
I have to implement a 3-state mac interface or there is a way using the mii interface with a 3-state switch?


top level code:

module top (
    // board clock&reset / leds&switches
    input               clk_board,      // 100MHz versa board clock    	
    input               reset_n,        // rst neg - push button       
    output	[7:0]  		led,            // led array                                           
    output  		    dp,             // 7-seg screen led                               
    input 	[7:0]    	sw,             // switches                                

    // Ethernet: 100BASE-T MII   
    input               phy_tx_clk,                                                                                    
    output [7:0]        phy_txd,                                                                                   
    output              phy_tx_en,                                 
                                                                              
    input               phy_rx_clk,                                                       
    input  [7:0]        phy_rxd,       
    input               phy_rx_dv,                
    input               phy_rx_er,  
	
    input               phy_col,                                                                                 
    input               phy_crs,  
    output              phy_mdc,                                                                       
    inout               phy_mdio,                                      
	
	input               phy_clk125,
    output              phy_rst_n
	);

// ------- rst_n & rst -------- //	
wire rst, rst_n;
reg [7:0] count; 
assign rst_n = (count > 8'b1111_1010) ? 1'b1 : 1'b0;
assign rst = !rst_n;
		
always @(posedge clk_100 or negedge reset_n) begin
	if (~reset_n)
		count = 8'b0000_0000;
	else if (count < 8'b1111_1101)
		count = count + 1;
end	


CLKDIVB clkdiv (
	.CLKI(clk_board), 
	.RST(1'b0), 
	.RELEASE(1'b1), 
	.CDIV1(clk_100), 
	.CDIV2(), 
	.CDIV4(clk_25), 
	.CDIV8()
);
	

// --- logic clock heart beat --- //
reg [23:0] heartbeat_cntr;
assign dp = heartbeat_cntr[23];

always @ (posedge phy_clk125 or negedge rst_n) begin
	if (~rst_n)
		heartbeat_cntr <= 24'h00_0000;
	else
		heartbeat_cntr <= heartbeat_cntr + 1;
end


ethernet_core ethernet_inst (
    .clk		 (phy_clk125),
    .rst		 (rst),
	.led		 (led),
 
    .phy_rx_clk	 (phy_rx_clk),
    .phy_rxd	 (phy_rxd[3:0]),
    .phy_rx_dv	 (phy_rx_dv),
    .phy_rx_er	 (phy_rx_er),
    .phy_tx_clk	 (phy_tx_clk),
    .phy_txd	 (phy_txd[3:0]),
    .phy_tx_en	 (phy_tx_en),
    .phy_col	 (phy_col),
    .phy_crs	 (phy_crs),
    .phy_rst_n   (phy_rst_n)
);

assign phy_txd[7:4] = 4'b0;
assign phy_mdc		= 1'b0;
assign phy_mdio		= 1'b0;


endmodule
	

ethernet core code:

module ethernet_core (
    input  wire       clk,
    input  wire       rst,
    output wire [7:0] led,

    input  wire       phy_rx_clk,
    input  wire [3:0] phy_rxd,
    input  wire       phy_rx_dv,
    input  wire       phy_rx_er,
    input  wire       phy_tx_clk,
    output wire [3:0] phy_txd,
    output wire       phy_tx_en,
    input  wire       phy_col,
    input  wire       phy_crs,
    output wire       phy_rst_n
);

// AXI between MAC and Ethernet modules
wire [7:0] rx_axis_tdata;
wire rx_axis_tvalid;
wire rx_axis_tready;
wire rx_axis_tlast;
wire rx_axis_tuser;

wire [7:0] tx_axis_tdata;
wire tx_axis_tvalid;
wire tx_axis_tready;
wire tx_axis_tlast;
wire tx_axis_tuser;

// Ethernet frame between Ethernet modules and UDP stack
wire rx_eth_hdr_ready;
wire rx_eth_hdr_valid;
wire [47:0] rx_eth_dest_mac;
wire [47:0] rx_eth_src_mac;
wire [15:0] rx_eth_type;
wire [7:0] rx_eth_payload_axis_tdata;
wire rx_eth_payload_axis_tvalid;
wire rx_eth_payload_axis_tready;
wire rx_eth_payload_axis_tlast;
wire rx_eth_payload_axis_tuser;

wire tx_eth_hdr_ready;
wire tx_eth_hdr_valid;
wire [47:0] tx_eth_dest_mac;
wire [47:0] tx_eth_src_mac;
wire [15:0] tx_eth_type;
wire [7:0] tx_eth_payload_axis_tdata;
wire tx_eth_payload_axis_tvalid;
wire tx_eth_payload_axis_tready;
wire tx_eth_payload_axis_tlast;
wire tx_eth_payload_axis_tuser;

// IP frame connections
wire rx_ip_hdr_valid;
wire rx_ip_hdr_ready;
wire [47:0] rx_ip_eth_dest_mac;
wire [47:0] rx_ip_eth_src_mac;
wire [15:0] rx_ip_eth_type;
wire [3:0] rx_ip_version;
wire [3:0] rx_ip_ihl;
wire [5:0] rx_ip_dscp;
wire [1:0] rx_ip_ecn;
wire [15:0] rx_ip_length;
wire [15:0] rx_ip_identification;
wire [2:0] rx_ip_flags;
wire [12:0] rx_ip_fragment_offset;
wire [7:0] rx_ip_ttl;
wire [7:0] rx_ip_protocol;
wire [15:0] rx_ip_header_checksum;
wire [31:0] rx_ip_source_ip;
wire [31:0] rx_ip_dest_ip;
wire [7:0] rx_ip_payload_axis_tdata;
wire rx_ip_payload_axis_tvalid;
wire rx_ip_payload_axis_tready;
wire rx_ip_payload_axis_tlast;
wire rx_ip_payload_axis_tuser;

wire tx_ip_hdr_valid;
wire tx_ip_hdr_ready;
wire [5:0] tx_ip_dscp;
wire [1:0] tx_ip_ecn;
wire [15:0] tx_ip_length;
wire [7:0] tx_ip_ttl;
wire [7:0] tx_ip_protocol;
wire [31:0] tx_ip_source_ip;
wire [31:0] tx_ip_dest_ip;
wire [7:0] tx_ip_payload_axis_tdata;
wire tx_ip_payload_axis_tvalid;
wire tx_ip_payload_axis_tready;
wire tx_ip_payload_axis_tlast;
wire tx_ip_payload_axis_tuser;

// UDP frame connections
wire rx_udp_hdr_valid;
wire rx_udp_hdr_ready;
wire [47:0] rx_udp_eth_dest_mac;
wire [47:0] rx_udp_eth_src_mac;
wire [15:0] rx_udp_eth_type;
wire [3:0] rx_udp_ip_version;
wire [3:0] rx_udp_ip_ihl;
wire [5:0] rx_udp_ip_dscp;
wire [1:0] rx_udp_ip_ecn;
wire [15:0] rx_udp_ip_length;
wire [15:0] rx_udp_ip_identification;
wire [2:0] rx_udp_ip_flags;
wire [12:0] rx_udp_ip_fragment_offset;
wire [7:0] rx_udp_ip_ttl;
wire [7:0] rx_udp_ip_protocol;
wire [15:0] rx_udp_ip_header_checksum;
wire [31:0] rx_udp_ip_source_ip;
wire [31:0] rx_udp_ip_dest_ip;
wire [15:0] rx_udp_source_port;
wire [15:0] rx_udp_dest_port;
wire [15:0] rx_udp_length;
wire [15:0] rx_udp_checksum;
wire [7:0] rx_udp_payload_axis_tdata;
wire rx_udp_payload_axis_tvalid;
wire rx_udp_payload_axis_tready;
wire rx_udp_payload_axis_tlast;
wire rx_udp_payload_axis_tuser;

wire tx_udp_hdr_valid;
wire tx_udp_hdr_ready;
wire [5:0] tx_udp_ip_dscp;
wire [1:0] tx_udp_ip_ecn;
wire [7:0] tx_udp_ip_ttl;
wire [31:0] tx_udp_ip_source_ip;
wire [31:0] tx_udp_ip_dest_ip;
wire [15:0] tx_udp_source_port;
wire [15:0] tx_udp_dest_port;
wire [15:0] tx_udp_length;
wire [15:0] tx_udp_checksum;
wire [7:0] tx_udp_payload_axis_tdata;
wire tx_udp_payload_axis_tvalid;
wire tx_udp_payload_axis_tready;
wire tx_udp_payload_axis_tlast;
wire tx_udp_payload_axis_tuser;

wire [7:0] rx_fifo_udp_payload_axis_tdata;
wire rx_fifo_udp_payload_axis_tvalid;
wire rx_fifo_udp_payload_axis_tready;
wire rx_fifo_udp_payload_axis_tlast;
wire rx_fifo_udp_payload_axis_tuser;

wire [7:0] tx_fifo_udp_payload_axis_tdata;
wire tx_fifo_udp_payload_axis_tvalid;
wire tx_fifo_udp_payload_axis_tready;
wire tx_fifo_udp_payload_axis_tlast;
wire tx_fifo_udp_payload_axis_tuser;

// Configuration
wire [47:0] local_mac   = 48'h00_01_02_03_04_05;
wire [31:0] local_ip    = {8'd192, 8'd168, 8'd33,  8'd69};
wire [31:0] gateway_ip  = {8'd192, 8'd168, 8'd33,  8'd1};
wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0};

// IP ports not used
assign rx_ip_hdr_ready = 1;
assign rx_ip_payload_axis_tready = 1;

assign tx_ip_hdr_valid = 0;
assign tx_ip_dscp = 0;
assign tx_ip_ecn = 0;
assign tx_ip_length = 0;
assign tx_ip_ttl = 0;
assign tx_ip_protocol = 0;
assign tx_ip_source_ip = 0;
assign tx_ip_dest_ip = 0;
assign tx_ip_payload_axis_tdata = 0;
assign tx_ip_payload_axis_tvalid = 0;
assign tx_ip_payload_axis_tlast = 0;
assign tx_ip_payload_axis_tuser = 0;

// Loop back UDP
wire match_cond = rx_udp_dest_port == 1234;
wire no_match = !match_cond;

reg match_cond_reg = 0;
reg no_match_reg = 0;

always @(posedge clk) begin
    if (rst) begin
        match_cond_reg <= 0;
        no_match_reg <= 0;
    end else begin
        if (rx_udp_payload_axis_tvalid) begin
            if ((!match_cond_reg && !no_match_reg) ||
                (rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin
                match_cond_reg <= match_cond;
                no_match_reg <= no_match;
            end
        end else begin
            match_cond_reg <= 0;
            no_match_reg <= 0;
        end
    end
end

assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond;
assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match;
assign tx_udp_ip_dscp = 0;
assign tx_udp_ip_ecn = 0;
assign tx_udp_ip_ttl = 64;
assign tx_udp_ip_source_ip = local_ip;
assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip;
assign tx_udp_source_port = rx_udp_dest_port;
assign tx_udp_dest_port = rx_udp_source_port;
assign tx_udp_length = rx_udp_length;
assign tx_udp_checksum = 0;

assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata;
assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid;
assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready;
assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast;
assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser;

assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata;
assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg;
assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg;
assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast;
assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser;

// Place first payload byte onto LEDs
reg valid_last = 0;
reg [7:0] led_reg = 0;

always @(posedge clk) begin
    if (rst) begin
        led_reg <= 0;
    end else begin
        if (tx_udp_payload_axis_tvalid) begin
            if (!valid_last) begin
                led_reg <= tx_udp_payload_axis_tdata;
                valid_last <= 1'b1;
            end
            if (tx_udp_payload_axis_tlast) begin
                valid_last <= 1'b0;
            end
        end
    end
end


assign led = led_reg;
assign phy_rst_n = !rst;


eth_mac_mii_fifo #(
    .TARGET("GENERIC"),
    .CLOCK_INPUT_STYLE("BUFR"),
    .ENABLE_PADDING(1),
    .MIN_FRAME_LENGTH(64),
    .TX_FIFO_DEPTH(4096),
    .TX_FRAME_FIFO(1),
    .RX_FIFO_DEPTH(4096),
    .RX_FRAME_FIFO(1)
)
eth_mac_inst (
    .rst(rst),
    .logic_clk(clk),
    .logic_rst(rst),

    .tx_axis_tdata(tx_axis_tdata),
    .tx_axis_tvalid(tx_axis_tvalid),
    .tx_axis_tready(tx_axis_tready),
    .tx_axis_tlast(tx_axis_tlast),
    .tx_axis_tuser(tx_axis_tuser),

    .rx_axis_tdata(rx_axis_tdata),
    .rx_axis_tvalid(rx_axis_tvalid),
    .rx_axis_tready(rx_axis_tready),
    .rx_axis_tlast(rx_axis_tlast),
    .rx_axis_tuser(rx_axis_tuser),

    .mii_rx_clk(phy_rx_clk),
    .mii_rxd(phy_rxd),
    .mii_rx_dv(phy_rx_dv),
    .mii_rx_er(phy_rx_er),
    .mii_tx_clk(phy_tx_clk),
    .mii_txd(phy_txd),
    .mii_tx_en(phy_tx_en),
    .mii_tx_er(),

    .tx_fifo_overflow(),
    .tx_fifo_bad_frame(),
    .tx_fifo_good_frame(),
    .rx_error_bad_frame(),
    .rx_error_bad_fcs(),
    .rx_fifo_overflow(),
    .rx_fifo_bad_frame(),
    .rx_fifo_good_frame(),

    .ifg_delay(12)
);

eth_axis_rx
eth_axis_rx_inst (
    .clk(clk),
    .rst(rst),
    // AXI input
    .s_axis_tdata(rx_axis_tdata),
    .s_axis_tvalid(rx_axis_tvalid),
    .s_axis_tready(rx_axis_tready),
    .s_axis_tlast(rx_axis_tlast),
    .s_axis_tuser(rx_axis_tuser),
    // Ethernet frame output
    .m_eth_hdr_valid(rx_eth_hdr_valid),
    .m_eth_hdr_ready(rx_eth_hdr_ready),
    .m_eth_dest_mac(rx_eth_dest_mac),
    .m_eth_src_mac(rx_eth_src_mac),
    .m_eth_type(rx_eth_type),
    .m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata),
    .m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid),
    .m_eth_payload_axis_tready(rx_eth_payload_axis_tready),
    .m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast),
    .m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser),
    // Status signals
    .busy(),
    .error_header_early_termination()
);

eth_axis_tx
eth_axis_tx_inst (
    .clk(clk),
    .rst(rst),
    // Ethernet frame input
    .s_eth_hdr_valid(tx_eth_hdr_valid),
    .s_eth_hdr_ready(tx_eth_hdr_ready),
    .s_eth_dest_mac(tx_eth_dest_mac),
    .s_eth_src_mac(tx_eth_src_mac),
    .s_eth_type(tx_eth_type),
    .s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata),
    .s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid),
    .s_eth_payload_axis_tready(tx_eth_payload_axis_tready),
    .s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast),
    .s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser),
    // AXI output
    .m_axis_tdata(tx_axis_tdata),
    .m_axis_tvalid(tx_axis_tvalid),
    .m_axis_tready(tx_axis_tready),
    .m_axis_tlast(tx_axis_tlast),
    .m_axis_tuser(tx_axis_tuser),
    // Status signals
    .busy()
);

udp_complete
udp_complete_inst (
    .clk(clk),
    .rst(rst),
    // Ethernet frame input
    .s_eth_hdr_valid(rx_eth_hdr_valid),
    .s_eth_hdr_ready(rx_eth_hdr_ready),
    .s_eth_dest_mac(rx_eth_dest_mac),
    .s_eth_src_mac(rx_eth_src_mac),
    .s_eth_type(rx_eth_type),
    .s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata),
    .s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid),
    .s_eth_payload_axis_tready(rx_eth_payload_axis_tready),
    .s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast),
    .s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser),
    // Ethernet frame output
    .m_eth_hdr_valid(tx_eth_hdr_valid),
    .m_eth_hdr_ready(tx_eth_hdr_ready),
    .m_eth_dest_mac(tx_eth_dest_mac),
    .m_eth_src_mac(tx_eth_src_mac),
    .m_eth_type(tx_eth_type),
    .m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata),
    .m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid),
    .m_eth_payload_axis_tready(tx_eth_payload_axis_tready),
    .m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast),
    .m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser),
    // IP frame input
    .s_ip_hdr_valid(tx_ip_hdr_valid),
    .s_ip_hdr_ready(tx_ip_hdr_ready),
    .s_ip_dscp(tx_ip_dscp),
    .s_ip_ecn(tx_ip_ecn),
    .s_ip_length(tx_ip_length),
    .s_ip_ttl(tx_ip_ttl),
    .s_ip_protocol(tx_ip_protocol),
    .s_ip_source_ip(tx_ip_source_ip),
    .s_ip_dest_ip(tx_ip_dest_ip),
    .s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata),
    .s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid),
    .s_ip_payload_axis_tready(tx_ip_payload_axis_tready),
    .s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast),
    .s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser),
    // IP frame output
    .m_ip_hdr_valid(rx_ip_hdr_valid),
    .m_ip_hdr_ready(rx_ip_hdr_ready),
    .m_ip_eth_dest_mac(rx_ip_eth_dest_mac),
    .m_ip_eth_src_mac(rx_ip_eth_src_mac),
    .m_ip_eth_type(rx_ip_eth_type),
    .m_ip_version(rx_ip_version),
    .m_ip_ihl(rx_ip_ihl),
    .m_ip_dscp(rx_ip_dscp),
    .m_ip_ecn(rx_ip_ecn),
    .m_ip_length(rx_ip_length),
    .m_ip_identification(rx_ip_identification),
    .m_ip_flags(rx_ip_flags),
    .m_ip_fragment_offset(rx_ip_fragment_offset),
    .m_ip_ttl(rx_ip_ttl),
    .m_ip_protocol(rx_ip_protocol),
    .m_ip_header_checksum(rx_ip_header_checksum),
    .m_ip_source_ip(rx_ip_source_ip),
    .m_ip_dest_ip(rx_ip_dest_ip),
    .m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata),
    .m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid),
    .m_ip_payload_axis_tready(rx_ip_payload_axis_tready),
    .m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast),
    .m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser),
    // UDP frame input
    .s_udp_hdr_valid(tx_udp_hdr_valid),
    .s_udp_hdr_ready(tx_udp_hdr_ready),
    .s_udp_ip_dscp(tx_udp_ip_dscp),
    .s_udp_ip_ecn(tx_udp_ip_ecn),
    .s_udp_ip_ttl(tx_udp_ip_ttl),
    .s_udp_ip_source_ip(tx_udp_ip_source_ip),
    .s_udp_ip_dest_ip(tx_udp_ip_dest_ip),
    .s_udp_source_port(tx_udp_source_port),
    .s_udp_dest_port(tx_udp_dest_port),
    .s_udp_length(tx_udp_length),
    .s_udp_checksum(tx_udp_checksum),
    .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata),
    .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid),
    .s_udp_payload_axis_tready(tx_udp_payload_axis_tready),
    .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast),
    .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser),
    // UDP frame output
    .m_udp_hdr_valid(rx_udp_hdr_valid),
    .m_udp_hdr_ready(rx_udp_hdr_ready),
    .m_udp_eth_dest_mac(rx_udp_eth_dest_mac),
    .m_udp_eth_src_mac(rx_udp_eth_src_mac),
    .m_udp_eth_type(rx_udp_eth_type),
    .m_udp_ip_version(rx_udp_ip_version),
    .m_udp_ip_ihl(rx_udp_ip_ihl),
    .m_udp_ip_dscp(rx_udp_ip_dscp),
    .m_udp_ip_ecn(rx_udp_ip_ecn),
    .m_udp_ip_length(rx_udp_ip_length),
    .m_udp_ip_identification(rx_udp_ip_identification),
    .m_udp_ip_flags(rx_udp_ip_flags),
    .m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset),
    .m_udp_ip_ttl(rx_udp_ip_ttl),
    .m_udp_ip_protocol(rx_udp_ip_protocol),
    .m_udp_ip_header_checksum(rx_udp_ip_header_checksum),
    .m_udp_ip_source_ip(rx_udp_ip_source_ip),
    .m_udp_ip_dest_ip(rx_udp_ip_dest_ip),
    .m_udp_source_port(rx_udp_source_port),
    .m_udp_dest_port(rx_udp_dest_port),
    .m_udp_length(rx_udp_length),
    .m_udp_checksum(rx_udp_checksum),
    .m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata),
    .m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid),
    .m_udp_payload_axis_tready(rx_udp_payload_axis_tready),
    .m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast),
    .m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser),
    // Status signals
    .ip_rx_busy(),
    .ip_tx_busy(),
    .udp_rx_busy(),
    .udp_tx_busy(),
    .ip_rx_error_header_early_termination(),
    .ip_rx_error_payload_early_termination(),
    .ip_rx_error_invalid_header(),
    .ip_rx_error_invalid_checksum(),
    .ip_tx_error_payload_early_termination(),
    .ip_tx_error_arp_failed(),
    .udp_rx_error_header_early_termination(),
    .udp_rx_error_payload_early_termination(),
    .udp_tx_error_payload_early_termination(),
    // Configuration
    .local_mac(local_mac),
    .local_ip(local_ip),
    .gateway_ip(gateway_ip),
    .subnet_mask(subnet_mask),
    .clear_arp_cache(0)
);

axis_fifo #(
    .DEPTH(8192),
    .DATA_WIDTH(8),
    .KEEP_ENABLE(0),
    .ID_ENABLE(0),
    .DEST_ENABLE(0),
    .USER_ENABLE(1),
    .USER_WIDTH(1),
    .FRAME_FIFO(0)
)
udp_payload_fifo (
    .clk(clk),
    .rst(rst),

    // AXI input
    .s_axis_tdata(rx_fifo_udp_payload_axis_tdata),
    .s_axis_tkeep(0),
    .s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid),
    .s_axis_tready(rx_fifo_udp_payload_axis_tready),
    .s_axis_tlast(rx_fifo_udp_payload_axis_tlast),
    .s_axis_tid(0),
    .s_axis_tdest(0),
    .s_axis_tuser(rx_fifo_udp_payload_axis_tuser),

    // AXI output
    .m_axis_tdata(tx_fifo_udp_payload_axis_tdata),
    .m_axis_tkeep(),
    .m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid),
    .m_axis_tready(tx_fifo_udp_payload_axis_tready),
    .m_axis_tlast(tx_fifo_udp_payload_axis_tlast),
    .m_axis_tid(),
    .m_axis_tdest(),
    .m_axis_tuser(tx_fifo_udp_payload_axis_tuser),

    // Status
    .status_overflow(),
    .status_bad_frame(),
    .status_good_frame()
);

endmodule

Is there any example for UDP stack + DHCP?

udp_complete.v works ok. Big thanks for nice udp stack implementation.

Also, it would be great to have DHCP support in order to obtain IP address automatically from the router. Is there any example? Thanks

tx parameters

Hi, I'm trying to modify the code. If not for loopback, how can determine values for below parametrs in fpga_core module:

tx_udp_hdr_valid
rx_udp_hdr_ready
tx_udp_length

Which NIC did you use for the AU50 example?

AU50 example does not work in my setup.

I think that the reason is my NIC (Intel XL710 for 40GbE QSFP+) and its settings (auto-negotiation).
Which NIC did you use for the AU50 example?
Do you have any suggestions for trouble shooting?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.