RfShotBuf
RfShotBuf is the finite sample buffer — load a waveform, then play it; capture into a region,
then transfer it. Because a writer and a reader never touch the same words at the same time there
is nothing to arbitrate in the streaming sense: no credit, no acknowledgements, no progress pointer,
no staleness margin. All of the memory is payload.
RfShotBufis a family name, not a class. There is noRfShotBufto import. The family is two concrete modules, and you reach for one of them by direction.
| class | module | example | RTL gate | |
|---|---|---|---|---|
| transmit — play a stored waveform | RfShotTx |
waveflow/hw/rf_shot_tx.py |
examples/rf_shot_tx |
tests/examples/test_rf_shot_tx_xsi.py |
| receive — capture continuously | RfShotRx |
waveflow/hw/rf_shot_rx.py |
examples/rf_shot_rx |
tests/examples/test_rf_shot_rx_xsi.py |
Both are built and gated at RTL, and both sit on the same primitive: a
LockedT2pMemIF — a lock channel over one true-dual-port BRAM,
which hands a region of the memory from one task to the other. That is what replaces the streaming
family’s whole reverse-channel apparatus, and it is why the two halves of this family have the same
shape.
They differ in how many regions they ask for, and that difference is not cosmetic:
RfShotTxholds one region and hands it back and forth. A load and a play therefore share addresses, in turn, and every handover costs a gap in the output.RfShotRxholds two and alternates. The writer and the reader are never in the same region, so there is nothing to hand over and nothing to gap.
The consequence is measured rather than argued, and it is on both pages.
Where to start
- Transmit —
RfShotTx— what to write to play a waveform: the ports, the in-band command, the four verdicts, the two play modes, and the rules that bite. - Receive —
RfShotRx— what to write to capture: the window header, whatn_droppedmeans, and why two regions make loss impossible rather than merely unlikely. - Internals — for developers and agents. The tasks, the channels, the lock protocol, the on-wire layouts and the findings that are easy to rediscover the hard way. Skip it if you only want to use the design.
The pair, worked through
- Measuring a delay with an address — both designs closed
through one converter with
absolute_index = 1, where the channel delay becomes a difference of memory addresses. It is also where the two per-design examples stop being enough: neither half can say the two ends are in the same phase, because neither has the other end.
Related
- Choosing a sample buffer — the one question that decides between this family and the streaming one, and what each gives up.
- Rfdc — the converter underneath, and the raw AXI-Stream interface this family sits on.
Table of contents
- Transmit — RfShotTx - Playing a stored waveform out of a converter: hand RfShotTx a shot once and it plays it a counted number of times or forever, answering every command with one verdict. The two-number geometry — the shot IS the buffer — the boundary ports, the in-band header and response as field tables, the two play modes and what a load arriving mid-play does to each, all four verdicts and which are transient, and the four rules that bite, including why the output is never silent and why a short transfer is a verdict rather than a hang.
- Receive — RfShotRx - Capturing samples out of a converter into a memory a reader drains behind it: RfShotRx fills one region while a reader drains the other, so nothing is dropped while the reader keeps up. The boundary ports, the window header as a field table, what n_dropped and CAP_LOST each answer and why both are needed, the build-time absolute_index that turns a drop from a shift into a hole, and the two rules an ADC-facing design cannot break — it may not stall, and it may not overwrite a region nobody has read.
- Internals - Internals of the RfShotBuf family for developers and agents: the three tasks and the composite that wires them, the lock protocol and the single ordering the whole thing turns on, every internal channel and why its depth is what it is, the on-wire bit layouts, the two hand-written task bodies, the measured II and cycle counts with the gate that produces each, and the findings that are easy to rediscover the hard way — the request/response deadlock, the reset trap, and why a yielded player still drives its read port.
- Options and what is not built - Where RfShotTx sits in the shot-buffer design space. Covers absolute indexing -- the build-time `absolute_index`, now on both halves, what it buys, what it costs on each side, where a hole is without a valid mask, and why shared addresses still need MTS -- what fixed-size relative indexing still costs you, and separately how much of the simulator's timing you are entitled to believe.