Capturing without losing anything
examples/rf_shot_rx is the worked example for RfShotRx — the
receive half of the finite sample buffer. An ADC plays samples in continuously; the design captures
them into a BRAM split into two regions, filling one while a reader drains the other, and hands
out each completed region as one frame.
This page is about the example. What the design is — the two regions, the rdy announcement,
what n_dropped and CAP_LOST each answer — is the guide’s.
RfDataSource --RFSampIF--> Rfdc.rx_rf | Rfdc.rx_streams[0] --> RfShotRx.samp_in
RfShotRx.w_out --> StreamSink (one FRAME per window: a header, then the samples)
The converter is really here, and the tile is ADC-only
n_rx=1, n_tx=0. The one thing a capture design exists to satisfy is that an ADC cannot be told to
wait, and the whole claim is that a window read-out does not make it wait either — so the converter
has to be in the graph rather than modelled away. Wiring a fake DAC in would add a metronome nothing
feeds.
There is no command stream
A capture is asked nothing. It is told when a region is ready by the design itself, and it answers
on every window with a header a host can act on. Compare
examples/rf_samp_buf_rx, whose whole middle is a command layer,
because its reader has to say which window it wants.
The scenario is the gate
The source plays a ramp of converter codes. So the windows the host receives must concatenate into a contiguous ramp — and a dropped block is a step in the numbers, visible whether or not anything counted it.
That is what makes nothing was lost checkable rather than merely reported. The strongest statement
in this example is not the drop counter; it is
test_the_rtl_captures_the_ramp_with_no_gap, which needs no counter to be believed. The header’s
n_dropped and status are asserted too, because the two agreeing is what says the design knows
what it lost.
The geometry
| value | what it is | |
|---|---|---|
depth |
256 words | the memory, split into N_REGION = 2 |
| region | 128 words | one window — depth / 2 |
blk_words |
16 | words per converter block: the chunk, the poll period, the output burst |
samp_rate |
256 MSa/s | the ADC’s grid |
| run | 40 blocks | long enough to fill several regions and hand out several windows |
depth must be a power of two — the address wrap is a mask — and blk_words is one number
serving four roles because they are one quantum: the converter’s block.
What it measures
| measurement | value | asserted by |
|---|---|---|
| ADC words captured | 640 | test_the_converter_never_had_a_word_refused |
| words dropped | 0 | same, and test_every_window_carries_CAP_OK_and_zero_lost |
| converter blocks | 40 | test_the_converter_never_had_a_word_refused |
| window words delivered | 516 | test_the_host_got_the_recorded_words_on_the_recorded_cycle |
| last window at cycle | 2205 | same |
| both memory ports live | 140 cycles | test_both_ports_are_live_together_and_never_in_the_same_region |
| writer and reader in the same region | 0 | same |
The last two are the pair that matters, and they are why this design has two regions where TX has one: the ports are busy together for 140 cycles — that is a true-dual-port memory doing its job — and they are never once inside the same region. On TX the same scan finds collisions, benign but non-zero. Here the question does not arise, by construction rather than by measurement.
Pages
- Running it — the build rungs, and what each produces.
- Taking it to RTL — the RTL run and every measured number, with its gate.
Related
RfShotRx— the design: the ports, the window header, the two rules an ADC-facing design cannot break.examples/rf_shot_tx— the transmit half of the same family.- Choosing a sample buffer — whether this family is the right one.
Table of contents
- Running it - The build rungs for rf_shot_rx and what each produces: the SimPy golden that checks the ramp is contiguous, the lowering to an ap_ctrl_none top plus its memory and wrapper, the XSI harness and the ramp bundle, and Vitis C-synthesis.
- Taking it to RTL - The XSI run for rf_shot_rx: nine gates, and every measured number with the assertion that pins it. The ramp arriving contiguous, the windows alternating between the two halves, every header carrying CAP_OK and zero lost, the converter never having a word refused, and the memory scan that finds both ports live together and never in the same region.