Skip to content

feat(b200_core): bump RX FIFO depths from 2K to 4K samples#14

Open
steve007iii wants to merge 2 commits into
lmesserStep:mainfrom
steve007iii:feat/larger-sample-fifo
Open

feat(b200_core): bump RX FIFO depths from 2K to 4K samples#14
steve007iii wants to merge 2 commits into
lmesserStep:mainfrom
steve007iii:feat/larger-sample-fifo

Conversation

@steve007iii

@steve007iii steve007iii commented May 1, 2026

Copy link
Copy Markdown

Summary

Bumps the RX-path FIFO depths in b200_core instantiation from 2K to 4K samples by overriding two parameters at the b200_core instantiation in libresdr_b210.v:

Parameter Default Override Role
SAMPLE_FIFO_SIZE 11 (2K) 12 (4K) Buffer feeding new_rx_framer (last stage before USB)
RADIO_FIFO_SIZE 11 (2K) 12 (4K) Cross-clock-domain FIFO (radio_clk ↔ bus_clk) in radio_legacy.v

Both FIFOs absorb transient backpressure between adjacent stages of the RX pipeline. Larger depths improve tolerance to host-side scheduling jitter (which causes overruns), particularly under Windows where libusb performance is roughly half of Linux.

Motivation

The current 2048-sample FIFOs are shallow enough that ordinary host scheduling jitter causes RX overruns.

Observed on B210mini (XC7A100T + AD9361) running the current bitstream:

  • Sustained benchmark_rate --rx_rate 5e6 --tx_rate 5e6 --duration 5 over USB 2.0
  • Result: 6 RX overruns, 654028 dropped samples, 0 sequence errors, 0 TX underruns

Changes

Single file, integration-level only. b200_core.v defaults unchanged.

// Before
b200_core #(.EXTRA_BUFF_SIZE(12)) b200_core

// After
b200_core #(
    .EXTRA_BUFF_SIZE(12),
    .SAMPLE_FIFO_SIZE(12),  // 4K samples (was default 11=2K)
    .RADIO_FIFO_SIZE(12)    // 4K samples (was default 11=2K)
) b200_core

No internal module logic touched; no clock-domain, reset, or AXI handshake changes.

Resource impact

Metric Before (size 11) After (size 12) Delta
FIFO depth (samples) 2048 4096 +2x
BRAM per RX channel (sample+radio) ~266 Kb ~532 Kb +266 Kb
BRAM total (2 channels) ~532 Kb ~1064 Kb +532 Kb
% of XC7A100T BRAM (4860 Kb) ~11% ~22% +11%
Worst-case latency at 61.44 MS/s 33 us 67 us +33 us

XC7A100T BRAM headroom remains comfortable (~78% free).

Why size 12 (4K) and not size 13 (8K)?

Considered both. Size 12 is the conservative choice:

  • Should resolve the bulk of overruns observed under Windows scheduling jitter.
  • BRAM overhead remains modest (~22% of total).
  • Latency impact stays in microsecond range at full sample rate.

If real-world testing shows residual overruns under heavier load, a follow-up PR could bump to size 13.

Testing status

  • Verilog parameter overrides are syntactically and semantically valid (matches existing pattern for EXTRA_BUFF_SIZE).
  • No changes to module internals; only instantiation-level parameters.
  • Bitstream not yet rebuilt by submitter — Vivado 2024.1 build cycle pending.
  • Hardware benchmark before/after pending — will follow up with benchmark_rate numbers in a PR comment once compiled.

Given the trivial scope of the change and the fact that b200_core already exposes both parameters as part of its public interface, opening this PR as-is and committing to follow up with measurements. Happy to mark as Draft if preferred.

Compatibility

  • No UHD-side changes required.
  • Does not affect FPGA Version register (still 16.0).
  • Backward-compatible with existing UHD 4.0+ host drivers tested in the current README.

Override SAMPLE_FIFO_SIZE from default 11 (2048 samples) to 12
(4096) at the b200_core instantiation in libresdr_b210.v. This
buffer feeds new_rx_framer and absorbs scheduling jitter between
the FPGA radio_clk domain and the USB host.

The 2K buffer is shallow enough that ordinary host scheduling
jitter causes RX overruns, particularly on Windows where libusb
has higher variance than Linux. Observed 6 overruns at 5 MS/s
sustained for 5 s on a B210mini over USB 2.0 with the current bin.

Resource impact: +133 Kb BRAM per channel (~+5% of XC7A100T total
4860 Kb). Latency worst-case adds +33 us at 61.44 MHz (negligible
for typical SDR workflows; non-blocking until FIFO fills).

Override applied at integration level; b200_core defaults unchanged.
Conservative 2x bump (size 12) chosen over more aggressive 4x (size
13) to keep BRAM footprint minimal.

Note: not yet re-validated on hardware after the change by submitter.
Plan to follow up with benchmark_rate before/after numbers once
Vivado 2024.1 build cycle is completed.
Apply the same depth bump to RADIO_FIFO_SIZE (cross-clock-domain
FIFO between radio_clk and bus_clk in radio_legacy.v) for symmetry
with the SAMPLE_FIFO_SIZE change in the previous commit.

Both FIFOs share the same role: absorbing transient backpressure
between adjacent stages of the RX/TX pipeline. RADIO_FIFO_SIZE
specifically handles the 150 MHz radio_clk to 200 MHz bus_clk
boundary, where async FIFO read/write rate mismatches can
accumulate during USB scheduling stalls.

Resource impact (cumulative with SAMPLE_FIFO_SIZE bump):
- Per RX channel: ~+266 Kb BRAM total (was +133 Kb)
- Both channels combined: ~+532 Kb BRAM (vs +266 Kb)
- % of XC7A100T BRAM (4860 Kb): ~11% (was ~5.5%)

Latency: worst-case +33 us added at 61.44 MS/s (negligible for
typical SDR workflows; only relevant when FIFO is fully populated).

Override applied at integration level only; b200_core defaults
unchanged.
@steve007iii steve007iii changed the title feat(b200_core): bump SAMPLE_FIFO_SIZE 2K -> 4K samples feat(b200_core): bump RX FIFO depths from 2K to 4K samples May 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant