Skip to content

Forty-Bot/ethernet

Repository files navigation

Verilog Ethernet

This repository is home to several cores which can be used to implement 100Base-X Ethernet PHYs, Hubs (Repeaters), and more. All cores are synchronous and are designed to be used in a single 125 MHz clock domain. These cores target Lattice iCE40 HX FPGAs (in terms of timing), but most modules are not specific to any FPGA.

Refer to documentation site for further details.

Building and testing

The following dependencies are required to build this project. Where known, specific minimum versions have been specified.

To build the example designs (under examples/), run

$ make -j$(nproc)

The outputs will be in their respective directories.

To run pre- and post-synthesis tests, run

$ make -j$(nproc) -O test

To run a pre-synthesis testbench, run

$ make MODULE.fst

where MODULE is the name of the module to test. To run post-synthesis simulation, run

$ make MODULE.synth.fst

You can view .fst files with GTKWave.

Resource usage

The following sections show device utilization reports for various configurations. All cores are verified to work at 125 MHz.

PHY with internal MII

These are the resources used by phy_internal with a minimal wrapper necessary to ensure proper timing:

LUTs WISHBONE ENABLE_COUNTERS

408

0

0

486

1

0

812

1

1

Modules

This section describes each module found in the rtl directory.

axis_replay_buffer

This module implements an AXI-stream FIFO that can be “replayed” indefinitely. That is, it will store the first BUF_SIZE cycles in a BRAM, and when requested it will send them over the master interface again. Once the buffer is exhausted it will wait for a replay or continue command. After continuing, it acts as a regular synchronous FIFO. This module is intended to help implementing half-duplex Ethernet MACs.

axis_mii_tx

This module implements the transmit half of a full- or half-duplex Ethernet MAC. It implements the full CS/CDMA algorithm, and automatically prepends an 8-byte preamble/SFD and appends a 4-byte FCS to the data. It currently only supports 100M ethernet, although 10M would be easy to add. I have no plans to support 1000M.

axis_wb_bridge

This module implements an AXI Stream to Wishbone bridge. This is not a more-typical DMA bridge, where streaming data is written in a fixed pattern. Rather, this module allows interactive or scripted examination and readout of a Wishbone bus. For more details on the protocol implemented by this bridge, refer to the UART-Wishbone Bridge documentation.

descramble

This implements a descrambler as specified in ANSI X3.264-1995 section 7.2.3. It uses the idle sections in the IPG to lock onto the far end’s scrambler. It typically acquires a lock after 29 bits of data, and will lose lock unless 29 idle bits are presented every 4500 bytes. Jumbo frames can be easily supported by modifying the unlock timeout value.

hub

This implements an N-port hub (repeater) as specified in IEEE 802.3 clause 29 with a Wishbone management interface. Each port implements a separate PHY (including a PCS) and an elastic buffer. The hub core reconciles incoming data and transmits it over other ports, generating jam bytes as necessary. At the moment, partitioning and link stability detection are not implemented.

hub_core

This implements the core hub functionality. It is completely stateless; it only creates jams when multiple ports have incoming data at the same time.

led_blinker

This implements LED blinking typical of switches and hubs. When triggered, the appropriate LED is activated at for one 30 Hz cycle. All LEDs blink in unison. This is suitable for displaying signals which would otherwise be too short to notice.

mdio

This is an MII Management Interface to Wishbone bridge. It decodes management frames as specified in IEEE 802.3 22.2.4.5. If the Wishbone slave times out or returns an error response, the MDIO line remains in high-impedance mode. This allows implementing the behavior for unimplemented registers specified in 22.2.4.3.

mdio_io

This module instantiates the appropriate I/O block for the MDC, MDIO signals, and an output-enable for an external level-shifter. It is intended for use with the mdio module.

mdio_regs

This module implements IEEE 802.3 clause 22 registers over a Wishbone interface. It may either be used with the mdio module or with an internal Wishbone bus. In addition to the standard MII registers, it also implements several error counter registers in the vendor-specific address space. Autonegotiation is not yet supported.

mii_elastic_buffer

This implements an elastic buffer for MII. It is a FIFO where data is only offered when the internal level reaches half-full. This allows smoothing out differences in clock speed between the local oscillator and the far end.

mii_io_rx

This module instantiates the appropriate I/O blocks for the receive MII signals (RX_CLK, RX_DV, RXD, and RX_ER). Due to differences in the local and far-end clock rates, the duty cycle of RX_CLK may vary, but will always remain within limits. Isolation is supported.

mii_io_tx

This module instantiates the appropriate I/O blocks for the transmit MII signals (TX_CLK, TX_EN, TXD, TX_ER). Isolation is supported.

nrzi_decode

This module decodes NRZI signals to NRZ.

nrzi_encode

This module encodes NRZ signals to NRZI.

pcs_rx

This module implements the receive half of a 100Base-X PCS as specified in IEEE 802.3 24.2. Internally, the pcs_rx_bits module performs the serial-to-parallel conversion and handles the alignment process. It is controlled by the pcs_rx module, which implements the main receive state machine. Back-to-back packets are not supported; at least two idle bits must be present between packets.

pcs_tx

This module implements the transmit half of a 100Base-X PCS as specified in IEEE 802.3 24.2. It is a fairly straightforward implementation of the state machine and encoding process.

phy_core

This module integrates the 100Base-X PCS and PMA, and the (de)scrambling part of the 100Base-T PMD. It coordinates loopback functionality. It also support collision testing.

pmd_dp83223

This module implements a 100Base-T PMD (except for (de)scrambling) when combined with a National Instruments DP83223 "Twister" transciever. The transmit half is quite simple, and most of the trick parts are implemented in the pmd_dp83223_rx module. This module support loopback.

pmd_dp83223_rx

This module interfaces with a DP83223 and brings its signals into the local clock domain. It uses 4x oversampling and determines an appropriate sample using the techniques described in Xilinx XAPP225 to select an appropriate sample. The specific implementation is a bit different since we use a 250 Mhz clock with a DDR FF (as opposed to four 125 MHz clocks in quadrature) and the selection process is split over several clock cycles. While most cycles will produce one bit of data, occasionally zero or two bits will be produced, due to differences in frequency between the local and far ends. This is a disadvantage when compared to a PLL-based solution, as the entire rest of the data path up to the PCS (when we can finally align the data) must handle these edge cases. However, it avoids the internal, nebulously-specified, and limited-in-number iCE40 PLLs.

reset_sync

This module synchronizes external reset signals (asynchronous assert and release) into the local clock domain (asynchronous assert, desynchronous release). A glitch filter suppresses spurious resets.

scramble

This module implements a scrambler as described in ANSI X3.264-1995 section 7.1.1.

uart_tx

A standard UART transmit module, accepting AXI-stream. 8n1 only. Supports 115,200 and 4,000,000 baud.

uart_rx

A standard UART receive module, outputting AXI-stream. 8n1 only. Supports 115,200 and 4,000,000 baud. Properly detects breaks as (single) frame errors, and ignores runt start bits.

uart_wb_bridge

This module combines the above UART cores with the AXI-stream bridge from before to allow controlling a Wishbone bus over a UART. There is no internal buffering, but some FIFOs could easily be added to allow more in-flight transactions. At the moment this only supports 16 data busses with 16-bit granularity. Frame errors (breaks) reset the bridge (but not the UARTs), providing an “out of band” ability for synchronization.

wb_mux

This implements a simple Wishbone mux, allowing a single master to access several slaves. The address decoding is greatly simplified by assigning each slave a (priority-decoded) address bit.

wb_reg

Add a register stage to a wishbone bus. This helps improve timing, but will add a cycle of latency (and decrease throughput).

Licensing

All cores are licensed under AGPL 3. See COPYING for details. Contact me if you are interested in using these cores under a different license.