Ethernet RF Stream
Raw Ethernet is used directly. There is no IP, UDP, or TCP layer.
This directory contains the shared host sender and the original VCU118 Ethernet
RF integration notes. Build the selected board bitstream with
RF_INPUT_MODE=ethernet; the default RF_INPUT_MODE=pmod removes the Ethernet
RF IP/RTL from the FPGA top.
Default host command using the C sender:
sudo make -C targets/fpga/vcu118 eth-rf-send
sudo make -C targets/fpga/genesys2 eth-rf-send
Python fallback:
sudo make -C targets/fpga/vcu118 eth-rf-send-python
sudo make -C targets/fpga/genesys2 eth-rf-send-python
SignalSim REAL4 generation
Generate single-channel real IF data from SignalSim. The file name may still
contain iq, but the .tag file must show IQ = 0.
SignalSim settings:
Format: REAL4
Sample MHz: 16.368
Desired IF MHz: 4.092
RF/LO Center MHz: 1571.328
Signal: GPS L1 C/A
GPS L1 is 1575.420 MHz, so:
1575.420 - 1571.328 = 4.092 MHz
Expected tag:
FMT = INT4
F_S = 16.368000
F_LO = 1571.328000
IQ = 0
BITS = 4
Do not use RF/LO Center MHz = 1571.420 for this flow. That puts GPS L1 at
4.000 MHz IF, while the current acquisition RTL is centered around
4.092 MHz.
Stream the generated REAL4 file with sign/magnitude conversion:
sudo make -C targets/fpga/vcu118 eth-rf-send \
ETH_RF_INPUT=/path/to/globsky_if_iq4.bin \
ETH_RF_SAMPLE_FORMAT=real4-signmag
Existing CATI RF dumps
/path/to/aa_july_cati2.bin is not packed two-samples-per-byte
SignalSim REAL4 data. Its bytes carry one 4-bit sample in the low nibble, so
stream it as raw-low4:
sudo make -C targets/fpga/vcu118 eth-rf-send \
ETH_RF_INPUT=/path/to/aa_july_cati2.bin \
ETH_RF_SAMPLE_FORMAT=raw-low4
Do not use real4-signmag for this file. That format splits each input byte
into two nibbles and inserts the zero high nibble as an extra RF sample, which
breaks acquisition/tracking.
Useful overrides:
sudo make -C targets/fpga/vcu118 eth-rf-send \
ETH_RF_IFACE=enx14ebb6850432 \
ETH_RF_INPUT=/path/to/globsky_if_iq4.bin \
ETH_RF_SAMPLE_FORMAT=real4-signmag
For a Globsky REAL8 output:
sudo make -C targets/fpga/vcu118 eth-rf-send \
ETH_RF_IFACE=enx14ebb6850432 \
ETH_RF_INPUT=/path/to/globsky_if_iq8.bin \
ETH_RF_SAMPLE_FORMAT=real8-to-4
Short link test:
sudo make -C targets/fpga/vcu118 eth-rf-send ETH_RF_MAX_SAMPLES=1000000
The default format treats the file as packed real 4-bit SignalSim samples. The Globsky file name may contain iq, but the .tag file is authoritative: use real4-signmag for SignalSim FMT = INT4, IQ = 0 and real8-to-4 for FMT = INT8, IQ = 0. The FPGA sends an ACK for every frame with FIFO credit. If the FIFO is near full, the host retries the same frame instead of advancing the file offset.
The RF port consumes one 4-bit sample per 16.368 MHz clock:
16.368 Msps * 4 bits = 65.472 Mbps = 8.184 MB/s
The host uses the C sender, jumbo raw Ethernet frames by default (ETH_RF_MTU=9000, ETH_RF_CHUNK_SAMPLES=17800), and preloads the FPGA FIFO before sending START (ETH_RF_PRELOAD_SAMPLES=131072). With 1500 MTU and 2800-sample chunks, Python had to wait for an ACK on too many small frames and measured about 10.3 Msps, which is not enough for continuous 16.368 Msps playback.
Measured short C test:
rate=16.397 Msps rf=65.589 Mbps 8.199 MB/s
min_fifo_level=71200 no_space=2808
no_space means the host was faster than the FPGA consumer and retried when the FIFO was near full; it is backpressure, not dropped data.
Supported ETH_RF_SAMPLE_FORMAT values:
real4-packed: packed real 4-bit samples, two samples per byte, high nibble first.real4-signmag: SignalSim/PocketSDR-style packed real 4-bit sign+magnitude samples converted to signed 4-bit two's complement.real8-to-4: signed 8-bit real samples converted to 4-bit signed samples.raw-low4: one 4-bit sample in each input byte's low nibble.raw-high4: one 4-bit sample in each input byte's high nibble.packed-high-first: two samples per byte, high nibble first.packed-low-first: two samples per byte, low nibble first in the file and converted on the wire.
FPGA defaults:
- Local MAC:
02:00:00:00:10:89 - EtherType:
0x88B6 - RF sample clock:
16.368 MHz