2023-03-15 13:27:42 -05:00
|
|
|
= Verilog Ethernet
|
2023-02-20 21:40:10 -06:00
|
|
|
|
2023-03-15 13:27:42 -05:00
|
|
|
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
|
2023-02-20 21:40:10 -06:00
|
|
|
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.
|
|
|
|
|
2023-03-15 13:27:42 -05:00
|
|
|
Refer to https://forty-bot.github.io/ethernet/[documentation site] for further
|
|
|
|
details.
|
|
|
|
|
2023-02-20 21:40:10 -06:00
|
|
|
== Building and testing
|
|
|
|
|
|
|
|
The following dependencies are required to build this project. Where known,
|
|
|
|
specific minimum versions have been specified.
|
|
|
|
|
|
|
|
- https://yosyshq.net/yosys/[Yosys] >= 0.4
|
|
|
|
- http://iverilog.icarus.com/[Icarus Verilog] >= 12.0
|
|
|
|
- https://www.cocotb.org/[cocotb]
|
|
|
|
- https://github.com/YosysHQ/nextpnr[nextpnr]
|
|
|
|
- https://clifford.at/icestorm[IceStorm]
|
|
|
|
|
|
|
|
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 https://gtkwave.sourceforge.net/[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.
|
|
|
|
|
2023-03-01 18:14:59 -06:00
|
|
|
=== `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 xref:doc/uart_wb_bridge.adoc#protocol[UART-Wishbone Bridge
|
|
|
|
documentation].
|
|
|
|
|
2023-02-20 21:40:10 -06:00
|
|
|
=== `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 https://docs.xilinx.com/v/u/en-US/xapp225[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.
|
|
|
|
|
2023-03-05 15:42:16 -06:00
|
|
|
=== `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.
|
|
|
|
|
2023-02-20 21:40:10 -06:00
|
|
|
=== `scramble`
|
|
|
|
|
|
|
|
This module implements a scrambler as described in ANSI X3.264-1995 section
|
|
|
|
7.1.1.
|
|
|
|
|
2023-02-27 22:20:56 -06:00
|
|
|
=== `uart_tx`
|
|
|
|
|
|
|
|
A standard UART transmit module, accepting AXI-stream. 8n1 only. Supports
|
|
|
|
115,200 and 4,000,000 baud.
|
|
|
|
|
2023-02-28 21:19:22 -06:00
|
|
|
=== `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.
|
|
|
|
|
2023-03-05 13:59:24 -06:00
|
|
|
=== `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.
|
|
|
|
|
2023-02-20 21:40:10 -06:00
|
|
|
=== `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.
|
|
|
|
|
2023-03-06 21:00:41 -06:00
|
|
|
=== `wb_reg`
|
|
|
|
|
|
|
|
Add a register stage to a wishbone bus. This helps improve timing, but will add
|
|
|
|
a cycle of latency (and decrease throughput).
|
|
|
|
|
2023-03-15 13:58:14 -05:00
|
|
|
|
|
|
|
== 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.
|