Implement generic MAX2771 raw Ethernet recorder
This commit is contained in:
@@ -0,0 +1,232 @@
|
||||
# MAX2771 raw recorder — Efinix Titanium Ti375 C529 kit
|
||||
|
||||
This is a separate board target for the Efinix Titanium Ti375 C529 development
|
||||
kit. It does not modify the Genesys 2 top-level, constraints, or Vivado flow.
|
||||
The protocol-compatible capture FIFO, packetizer, CRC and raw Ethernet MAC are
|
||||
the read-only common RTL in `../../rtl/common`; every Efinix-specific source is
|
||||
contained in this directory and the source list is explicit in
|
||||
`scripts/generate_project.py`.
|
||||
|
||||
No RISC-V/SoC block, CPU, AXI fabric, generated Ethernet MAC, IP stack, or
|
||||
Efinix Ethernet IP is used. Only the Efinity periphery resources needed for
|
||||
GPIO DDIO and PLL clocking are generated.
|
||||
|
||||
## Data path
|
||||
|
||||
```text
|
||||
MAX2771 J13/PMOD0
|
||||
clock -> A12/GPIOR_95_CLK12 global clock -> GPIO DDR input registers
|
||||
data ---------------------> rising/falling sample selection
|
||||
-> sample index + loss marker
|
||||
-> handwritten 16,384 x 69 async FIFO
|
||||
-> 2936-sample packetizer
|
||||
-> handwritten Ethernet MAC/FCS
|
||||
100 MHz oscillator -> Ethernet PLL -> 125 MHz / 125 MHz +90 degrees
|
||||
-> GPIO DDIO RGMII -> RTL8211FDI -> RJ45
|
||||
```
|
||||
|
||||
`CAPTURE_RISING=1` selects the GPIO `_HI` samples; `0` selects `_LO` samples.
|
||||
`EARLIER_SAMPLE_HIGH_NIBBLE=1` produces the required byte order: earlier sample
|
||||
in bits 7:4, later sample in bits 3:0.
|
||||
|
||||
## MAX2771 wiring
|
||||
|
||||
Use J13, identified as PMOD0 in the official kit guide. The PMOD header is
|
||||
3.3 V. Do not reuse the Genesys 2 JA ball names on this board.
|
||||
|
||||
| RTL signal | J13 pin | Ti375 logical pin | C529 ball | Level |
|
||||
|---|---:|---|---|---|
|
||||
| RF clock input | 10 | GPIOR_95_CLK12 | A12 | 3.3 V |
|
||||
| data bit 0 | 2 | GPIOR_89 | G16 | 3.3 V |
|
||||
| data bit 1 | 3 | GPIOR_90 | F16 | 3.3 V |
|
||||
| data bit 2 | 4 | GPIOR_91 | F17 | 3.3 V |
|
||||
| data bit 3 | 7 | GPIOR_92 | G17 | 3.3 V |
|
||||
| ground | 5 or 11 | — | — | 0 V |
|
||||
| PMOD supply | 6 or 12 | — | — | 3.3 V |
|
||||
|
||||
The MAX2771 clock-to-data minimum/maximum values and cable/adapter skew are not
|
||||
known. Interface Designer generates constraints for its internal GPIO register
|
||||
paths; those numbers are not a substitute for MAX2771 external timing. Measure
|
||||
or obtain the external values before claiming complete board-level RF input
|
||||
timing closure. See `docs/hardware_assumptions.md`.
|
||||
|
||||
## Ethernet hardware
|
||||
|
||||
The board PHY is RTL8211FDI and the RGMII bus is 1.8 V. The board straps PHY
|
||||
address 2, receive delay enabled and transmit delay disabled. Receive is not
|
||||
implemented. The FPGA creates the required transmit-clock phase shift with a
|
||||
125 MHz, +90-degree PLL output and sends TXD/TXCTL with the unshifted 125 MHz
|
||||
clock. PHY reset remains low for 10 ms, followed by a 30 ms settle period.
|
||||
|
||||
The MDIO controller selects Realtek page `0xa43`, reads PHYSR register `0x1a`,
|
||||
restores page 0, and only asserts `link_ready` for real-time link=1,
|
||||
speed=1000 Mb/s and full duplex. A 100 Mb/s link deliberately transmits no
|
||||
frames: the 130.944 Mb/s raw sample stream already exceeds a 100 Mb/s line
|
||||
before Ethernet overhead.
|
||||
|
||||
## Clocks
|
||||
|
||||
| Function | Source | PLL | Outputs |
|
||||
|---|---|---|---|
|
||||
| Ethernet | board 100 MHz oscillator, U4 | PLL_BL0, EXT_CLK1 | CLK0 100 MHz dummy, CLK1 125 MHz, CLK2 125 MHz +90° |
|
||||
| RF capture | MAX2771 clock, J13.10/A12 | direct GPIOR_95_CLK12 GCLK | nominal 32.736 MHz |
|
||||
|
||||
The 100 MHz dummy output satisfies the Titanium CLKOUT0 restriction. The
|
||||
Ethernet PLL outputs and their physical reference resources are checked by the Efinity
|
||||
Interface Designer API during every build. The direct RF GCLK period defaults
|
||||
to 30.547 ns and can be overridden with `RF_CLOCK_PERIOD_NS` when the actual
|
||||
MAX2771 clock differs.
|
||||
|
||||
## Raw Ethernet protocol
|
||||
|
||||
Frames use destination `ff:ff:ff:ff:ff:ff`, source `02:27:71:00:00:01`, and
|
||||
EtherType `0x88b5`. A normal Ethernet payload is exactly 1500 bytes: the
|
||||
32-byte `MX27` header followed by 1468 packed bytes/2936 samples. All metadata
|
||||
is network byte order. The byte protocol is unchanged from
|
||||
[`docs/raw_ethernet_protocol.md`](../../docs/raw_ethernet_protocol.md).
|
||||
|
||||
The FPGA emits preamble, SFD, Ethernet header, payload, FCS and 12-byte IFG.
|
||||
Normal host NICs remove preamble/SFD/FCS before delivery to `AF_PACKET`.
|
||||
|
||||
## Efinity headless CLI build
|
||||
|
||||
“Non-project mode” is Vivado terminology and is not used here. This target has
|
||||
the Efinity equivalent headless flow: scripts generate the periphery and a
|
||||
temporary project XML, then invoke the supported command-line compile flow.
|
||||
|
||||
The installed path on this machine is:
|
||||
|
||||
```bash
|
||||
export EFINITY_HOME=/tools/efinix/efinity/2026.1
|
||||
cd targets/efinix_ti375_c529
|
||||
make build
|
||||
```
|
||||
|
||||
Outputs are under `build/outflow/`, including the pinout, interface timing,
|
||||
synthesis, P&R, timing reports and `ti375_max2771_recorder.bit`. The script
|
||||
fails on API/DRC/compile errors, absent required clocks, missing timing report,
|
||||
negative timing slack, or missing bitstream.
|
||||
|
||||
The final A12/GPIOR_95 Efinity 2026.1 C4 build completed successfully on
|
||||
1 August 2026. Post-route slack was +0.636 ns setup/+0.094 ns hold at 125 MHz
|
||||
and +25.614 ns setup/+0.031 ns hold at 32.736 MHz. The generated CDC report says
|
||||
`No Synchronizer warnings to report`. Placement used 36,253/362,880 XLRs
|
||||
(9.99%), 138/2,688 memory blocks (5.13%), and no DSP blocks.
|
||||
|
||||
The kit guide revision describes a C4 timing grade and the local Efinity kit
|
||||
example also uses C4. Confirm the marking on the actual FPGA. Override only the
|
||||
timing model, not the base package device, when necessary:
|
||||
|
||||
```bash
|
||||
EFINIX_TIMING_MODEL=I3 make build
|
||||
```
|
||||
|
||||
## Programming
|
||||
|
||||
Connect the board USB/JTAG interface, power the fan as required by the kit, and
|
||||
run:
|
||||
|
||||
```bash
|
||||
export EFINITY_HOME=/tools/efinix/efinity/2026.1
|
||||
make program
|
||||
```
|
||||
|
||||
This calls `efx_run.py ... --flow program --pgm_opts mode=jtag` with the
|
||||
generated `.bit` file. It does not alter the boot flash.
|
||||
|
||||
For an RF-independent physical Ethernet test, a separate diagnostic top-level
|
||||
generates the repeating nibble sequence 0 through 15 and uses the production
|
||||
packetizer, MAC, FCS, MDIO and RGMII blocks:
|
||||
|
||||
```bash
|
||||
make selftest-build
|
||||
make selftest-program
|
||||
```
|
||||
|
||||
Restore the recorder afterwards with `make program`; JTAG configuration is
|
||||
volatile. On the tested board/direct cable, a 3.034-second self-test capture
|
||||
received 35,446 consecutive frames/104,069,456 samples with no protocol gap,
|
||||
FPGA drop, socket drop, or pattern mismatch.
|
||||
|
||||
## Host capture
|
||||
|
||||
The raw protocol and host application are board-independent:
|
||||
|
||||
```bash
|
||||
make -C ../../host
|
||||
sudo ip link set dev enp3s0 up
|
||||
sudo ip addr flush dev enp3s0
|
||||
sudo ethtool enp3s0
|
||||
sudo ethtool -K enp3s0 gro off lro off # unsupported options may be ignored
|
||||
sudo sysctl -w net.core.rmem_max=268435456
|
||||
sudo ../../host/max2771_raw_rx \
|
||||
--interface enp3s0 \
|
||||
--output max2771_capture.bin \
|
||||
--gap-mode zero-fill
|
||||
```
|
||||
|
||||
No IP address, ARP or firewall change is required. Prefer a direct cable or an
|
||||
isolated switch because every frame is broadcast. For non-root operation:
|
||||
|
||||
```bash
|
||||
sudo setcap cap_net_raw,cap_net_admin=eip ../../host/max2771_raw_rx
|
||||
```
|
||||
|
||||
Use a dedicated Gigabit NIC and storage capable of sustained writes above
|
||||
16.368 MB/s.
|
||||
|
||||
## Throughput
|
||||
|
||||
At 32.736 Msps, the source is 130.944 Mb/s (16.368 MB/s). Full frames occur at
|
||||
approximately 11,149.864 frames/s. Including preamble/SFD, MAC header, 1500-byte
|
||||
payload, FCS and IFG, each frame occupies 1538 byte-times, or 12,304 bits. Line
|
||||
use is approximately 137.188 Mb/s, 13.719% of 1 Gb/s; raw line-rate margin is
|
||||
about 7.29x.
|
||||
|
||||
The current packetizer first loads a frame buffer and then transmits it. At 125
|
||||
MHz, its conservative three-clock read handshake loads 2936 samples in about
|
||||
70.464 us; the frame plus IFG takes 12.304 us. This gives about 8.3% scheduler
|
||||
margin over the required frame rate. During loading the FIFO drains faster than
|
||||
the RF source; during frame transmission about 403 new samples arrive. In
|
||||
steady state it reaches the 2936-sample launch threshold, finishes near 2709
|
||||
samples, then refills. Link-down occupancy can instead reach the full 16,384
|
||||
entries; all further input samples are counted as drops, never overwritten.
|
||||
|
||||
## LEDs
|
||||
|
||||
| LED | Meaning |
|
||||
|---|---|
|
||||
| LED9 | Ethernet PLL/reset system ready; may toggle only while Ethernet PLL is acquiring lock |
|
||||
| LED10 | qualified 1000/full link ready |
|
||||
| LED11 | RF sample activity |
|
||||
| LED12 | FIFO has data; frame-count divider gives visible TX activity |
|
||||
| LED13 | FIFO overflow/sample loss latched |
|
||||
|
||||
There are five verified user LEDs, so FIFO and transmit activity share LED12.
|
||||
|
||||
## Simulation
|
||||
|
||||
```bash
|
||||
cd targets/efinix_ti375_c529
|
||||
make sim
|
||||
```
|
||||
|
||||
The target tests verify RGMII half-cycle/control mapping and RTL8211FDI PHYSR
|
||||
link qualification/link-down counting. The script then runs the full shared
|
||||
recorder regression: standard CRC vector, complete Ethernet bytes/FCS/IFG,
|
||||
random async FIFO CDC, two-frame sample reconstruction, header/index/sequence,
|
||||
reset behavior and overflow handling.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- No Ethernet frames: verify `ethtool` reports 1000 Mb/s/full duplex and LED10
|
||||
is on. A 100 Mb/s negotiation is intentionally rejected.
|
||||
- LED13 on before link: capture cannot be backpressured; the FIFO fills while
|
||||
link is unavailable, and the loss is correctly counted.
|
||||
- Interface DRC failure: check that the base device is `Ti375C529` and the
|
||||
board wiring/pins have not been changed.
|
||||
- RF timing failure or corrupted nibbles: confirm 3.3 V levels, ground, capture
|
||||
edge and the actual MAX2771 clock-to-data window with measurement.
|
||||
- Efinity warns about `libstdc++.so`: this is emitted by the installed 2026.1
|
||||
setup script on this host. Do not delete tool files automatically; follow the
|
||||
vendor’s installation guidance if the tools fail to run.
|
||||
Reference in New Issue
Block a user