Hey Michael,\ \ Just to give some context:\ \ **Regarding EoB and EoV**:\ [In RFNoC, a burst denotes a series of contiguous samples.](https://uhd.readthedocs.io/en/latest/page_rfnoc_fpga.html#autotoc_md212)\ In practice, and specifically in the context of samples and the radio block, this means that if you are sending data packets to the radio, the radio expects you to provide it with enough data such that for each clock cycle of the radio clock, the radio has a new sample that it can transmit.\ If you do not tell the radio block that you want to stop transmitting data, and just stop providing new samples, the the radio will run out of samples and generate an Underflow warning, that it sends to the host(usually a “U” in the terminal output).
The radio block internally has some space to buffer samples ahead of time and also support flow control/backpressure via the AXI-Stream Handshaking interface(tvalid/tready) so usually you can just send data as fast as you can, and let the back-pressure mechanism worry about ensuring that the radio always has data to send. In this context, the EoB flag is meant as a signal to the Radio block that you will not be providing further samples and that the radio block should therefore not expect additional samples coming in after the current packet with the EoB flag. This means that implicitly, every time the you are sending data to the radio, the radio assumes that this is the start of a new burst, and the radio will therefore assume that more data is coming unless you set the EoB flag in the packet that contains the end of the samples you want to transmit. \ When streaming from the host, the UHD driver will take care of this for you and automatically set the EoB flag, unless you manually override this. The EoV flag on the other hand, as others have already mentioned, is meant to logically distinguish different units of your contiguous stream of samples. How each Block interprets the EoV is implementation dependent and actually most blocks do not even check it.\ It is mostly meant as a tool for users to compartmentalize samples in order to do some sort of batch processing in a custom block on the FPGA.\ Some examples here are 5G radio frames, that are comprised of contiguous samples that cover the full frame, but depending on your configuration, the frame can be subdivided into different slots, that a custom block might want to process individually. If one of these slots is too big to encapsulate into a single packet, it can make sense to use the EoV flag to indicate slot boundaries.\ Another example could be the FFT-size, as was already mentioned in this thread.\ \ **Regarding Timestamps**:\ I am making the assumption that you are only talking about timestamps as they relate to IQ data, and are not talking about timed (control) commands here. RFNoC provides the option to do timed and untimed data streaming. Again, technically how a block processes the timestamps depends on the type of block. I will only talk about how the radio block interprets the timestamp as the radio block is an integral part of almost every design. When you are requesting samples from the radio block starting at a specific point in time, this is what we usually call timed RX streaming. The radio block will start sending packets as soon as the time start time that was specified arrives and will start sending out a new burst of samples until either the specified number of samples have been sent, or the radio receives a stop command to stop sending RX samples(EoB is set for the last packet).\ \ Timed streaming means that the [RFNoC CHDR packet type](https://uhd.readthedocs.io/en/latest/page_rfnoc_fpga.html#autotoc_md210) used to transmit these samples has additional timestamp information included in the header(CHDR packet type 0x7 => “data with timestamp”) For the first packet of the timed streaming burst the timestamp is mandatory, and the timestamp always refers to the first sample contained in the payload of a CHDR data packet. E.g. if your packet has a timestamp of 0x1000, that means that the radio received sample_0 at time 0x1000, sample_1 at 0x1001, sample_2 at 0x1002, etc. for all samples of the CHDR packet.\* Since we already know that a burst always contains contiguous samples without any gaps as it relates to the radio sampling clock\*, subsequent packets of the same burst technically do not need to include a timestamp, as we have all information available to calculate the time for each sample just with the timestamp of the first packet and the number of samples that have been received already, but for convenience subsequent packets can still include timestamps, as long as they match the correct time at which the first sample of each packet is received/transmitted by the radio.\ \ If you are incorrectly setting the timestamp manually in your custom block and then are forwarding the packets to the radio, if there are any gaps between the calculated timestamp of the last sample of the previous packet and the timestamp corresponding to the first sample of the current packet, the radio will notice the missmatch and in the case that this leads to timestamps where the radio does not have any valid samples to send will generate an Underflow (“U”). \ This is probably what you were seeing in your implementation, if your are pausing between sending packets to the Radio as you stated in your initial question.\ As stated above, you do not have to worry that you will fill up the buffers as there should be backpressure mechanisms in place that will prevent overflowing the radio transmit buffers.\ Of course it is your own responsibility to ensure that your custom IP also correctly adheres to the AXI-Stream handshaking rules internally. If you want to get access to the internal device time there are multiple ways this can be done, but I will only mention the two most common ones here: * From Host: There are API functions to get the current device time from the USRP device timerkeeper. Usually the main device timer is accessible via the Motherboard interface, and there are functions like [get_tick_rate()](https://uhd.readthedocs.io/en/latest/classuhd_1_1rfnoc_1_1mb__controller_1_1timekeeper.html#ac578c97f308f7ab99ece620cae6c3368) to get the current device tick rate, as well as [get_ticks_now()](https://uhd.readthedocs.io/en/latest/classuhd_1_1rfnoc_1_1mb__controller_1_1timekeeper.html#a17738f2ce94478654151c265df75cff1) and [get_ticks_last_pps()](https://uhd.readthedocs.io/en/latest/classuhd_1_1rfnoc_1_1mb__controller_1_1timekeeper.html#aff03009ee9343e9e36669072a68eb769). \ You could use the host TX/RX streamers to do timed streaming from the host via your custom block and just route the packets through your processing block and do not touch the timestamps at all. If you send th edata down far enough ahead of time for your processing to be finished by the time the packets reach the radio block, you probably will not have to touch the timestamps at all in your custom block on the FPGA.\ If you do want to manually set the timestamps, you could query the time from the host, calculate a relative time in advance for your processing and then send this time down to your custom block via the register interface and use this timestamp to set the correct header fields in the packet your custom block is processing. [Have a look at the different Data interface types you can configure for your custom blocks CHDR data interface here.](https://uhd.readthedocs.io/en/latest/page_rfnoc_fpga.html#autotoc_md236) * From the FPGA: You can configure your custom block to have direct access to the Motherboard timekeeper by adding the timekeeper port to your block description when you generate your block template. [See the radio block block description for an example.](https://github.com/EttusResearch/uhd/blob/master/host/include/uhd/rfnoc/blocks/radio.yml#L77C3-L82C54) If this port is available for your custom block, you can connect it to the global timekeeper by adding the connection in your rfnoc_image_core.yml file when you instantiate your block, again [see the radio block as an example](https://github.com/EttusResearch/uhd/blob/master/fpga/usrp3/top/x400/yaml_include/x410_radio_base.yml#L49) of how to add this in your connections section. \ Sorry for the wall of text, I just had the impression that some more background might be helpful to better understand how to integrate your own block into the existing RFNoC infrastructure.\ \ Hope this helps put everything into the proper context.\ \ Regards, \ Niels \ \ \* Unless of course the samples were previously decimated and therefore do not have the same sampling rate as the radio. --- Martin Braun wrote: > Even if the processing does not touch the host, then unless you're doing > something crazy, you are still running UHD to set up the session, configure > the radio, etc. That's where you can get your timestamp from. Typically, > you would know when to send based on what your algorithm is. > > \--M > > On Thu, Mar 26, 2026 at 6:55 PM Barnard, Michael T < > [email protected]> wrote: > > > Thanks for the insight; I've got a better handle on things now. I'm still > > not sure where to get the timestamp value from. The processing doesn't > > touch the host PC at all everything is contained in the FPGA. Is the > > timestamp distributed to the cores or do I need to request the value from > > somewhere else in the FPGA? > > > > *Michael Barnard* > > > > TL Computer Engineer, Scalable Computing Group > > > > Applied Sensing Division > > > > 300 College Park, Dayton, OH 45469-0031 > > > > O:(937) 713-4271 | C:(440) 622-6486 | udri.udayton.edu > > > > \[image: 1621527942842\] > > > > ## UDRI Proprietary - Unprotected > > > > *From:* Martin Braun [[email protected]](mailto:[email protected]) > > *Sent:* Thursday, March 26, 2026 9:30 AM > > *Cc:* [email protected] > > [[email protected]](mailto:[email protected]) > > *Subject:* \[USRP-users\] Re: X310 Precise Transmit Control > > > > CAUTION: This email originated from outside of the organization. Do not > > click links or open attachments unless you recognize the sender and know > > the content is safe. > > > > Some additional comments: > > > > * You can probably ignore EOV > > * If you do use EOV, note that it is treated differently than EOB in some > > places. For example, the recv() call (in software) will terminate > > immediately when it sees an EOB, but you can have multiple EOVs in a > > single > > burst (so from that recv() call, you can never have more than one EOB, but > > any number of EOVs). > > * If you come from a strict FPGA background, it's important to get behind > > the "network on chip" part of RFNoC. Your clocks don't really matter here. > > What matters is, when the radio gets a CHDR packet, it will read the > > timestamp and compare it against the corresponding timer. When a CHDR > > packet leaves one block, you shouldn't care (at design time) if the next > > block is right next to it, or 100 km away over an Ethernet line. I'm > > exaggerating, but I hope this helps understand this concept. > > > > \--M > > > > On Wed, Mar 25, 2026 at 9:56 PM Brian Padalino > > [[email protected]](mailto:[email protected]) > > wrote: > > > > On Wed, Mar 25, 2026 at 4:41 PM Barnard, Michael T < > > [email protected]> wrote: > > > > I am a FPGA developer working in Verilog with an X310 writing code in a > > custom RFNoC block. I recently got independent streaming control working to > > output samples at my discretion to a streaming endpoint then through the > > cross bar but I do have some questions on parts of the control behavior. > > It’s not clear to me what the difference between End of Burst (EOB) and > > End of Vector (EOV) is or when I need to use one or the other. My current > > design only uses EOB on the last data packet while EOV is always set to 0. > > I’m getting underflow errors occasionally but I can’t confidently say which > > packets they’re associated with. I also need to send a second packet with > > EOB high to flush the first packet out of the buffer; my guess would be > > that the first EOB would force a buffer flush. Is there any > > > > EOV was added for when your data might be too large for a single CHDR > > packet. Think like a 16384 sample FFT frame - it can't fit inside a single > > CHDR packet, so EOV is used. > > > > I’m also wondering if there is a way to precisely schedule samples or > > packets for transmit out of the radio. I’ve observed that because the data > > is processed at \~215 MHz in the RFNoC block and fed into the DAC at 200 MHz > > pauses have to be included between each packet to prevent overfilling the > > transmit buffer but this also means that a timing in the 215 MHz domain may > > not be reflected in the 200 MHz domain. Is there a way to tell the transmit > > logic/front end to start transmitting at a particular time either in the > > CHDR header or using the timestamp? Or am I at the mercy of the front end > > components without any fine control of transmit timing? > > > > The CHDR with Timestamp is used there. When it's the first packet in a > > burst, that time is compared against the timestamp of the radio. If it's > > late, then the radio sets an error condition that is sent back to the host > > and the radio block will consume the packets as fast as possible until it > > sees the EOB. There are other modes of operation depending on how you set > > up your RFNoC graph as to what to do during these error conditions. Check > > the state machine here: > > > > https://github.com/EttusResearch/uhd/blob/master/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_radio/radio_tx_core.v#L299 > > \[github.com\] > > <https://urldefense.us/v2/url?u=https-3A__github.com_EttusResearch_uhd_blob_master_fpga_usrp3_lib_rfnoc_blocks_rfnoc-5Fblock-5Fradio_radio-5Ftx-5Fcore.v-23L299&d=DwMFaQ&c=pftDoUyzvDgNGToC1TC2fAYTjbKPSqv0CTWoNdikfI0&r=_YNw12ReY4H38tz6L9d14UI9KmDH4TWmWo4TzJSbxw9SuCqdtK-AT-259kfxeZsh&m=bVvtqauPQKkwOFyp6pIaqyonQasy1o456UpJAuwvY8AZOSrv24SufW7pJZTEFIdS&s=svYWjmrncxL4sI1kllS9riUDzvO1tNla7wsRZ66__Lc&e=> > > > > As for the processing clock versus radio clock, you should be adhering to > > the AXI streaming tready signal for back pressure. You can fill up that > > pipeline and things should be fine. > > > > Good luck. > > > > Brian > > > > --- > > > > USRP-users mailing list -- [email protected] > > To unsubscribe send an email to [email protected] > > > > --- > > > > The information contained in this e-mail and any attachments from UDRI may > > contain confidential and/or proprietary information, and is intended only > > for the named recipient to whom it was originally addressed. If you are not > > the intended recipient, any disclosure, distribution, or copying of this > > e-mail or its attachments is strictly prohibited. If you have received this > > e-mail in error, please notify the sender immediately by return e-mail and > > permanently delete the e-mail and any attachments. > > > > --- > > > > USRP-users mailing list -- [email protected] > > To unsubscribe send an email to [email protected]
_______________________________________________ USRP-users mailing list -- [email protected] To unsubscribe send an email to [email protected]
