Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a pulse-train stream mode (for RFNoC) #787

Open
andsunds opened this issue Sep 27, 2024 · 4 comments
Open

Add a pulse-train stream mode (for RFNoC) #787

andsunds opened this issue Sep 27, 2024 · 4 comments

Comments

@andsunds
Copy link

Issue Description

I need to be able to transmit and receive a large number (~1000) of pulses in a regular sequence, with a pulse repetition frequency of at least >~10 kHz (<~100 us between Tx/Rx burst starts).

If I try to issue these commands as timed command in advance, I get RfnocError: OpFailed: [Replay] Play command queue is full after the ~32 first commands. This error message stems from the Tx command replay_Tx.issue_stream_cmd(stream_cmd_Tx, 0). Interestingly I don't get an error message when I only issue the Rx command radio_chan_Rx.issue_stream_cmd(stream_cmd_Rx, 0), even though the recording has clearly stopped after the first ~32 pulses.

Would it be possible to add a pulse-train stream mode functionality to the RFNoC modules? The stream command could look something like:

stream_mode               = uhd.types.StreamMode.pulse_train
stream_cmd                = uhd.types.StreamCMD(stream_mode)
stream_cmd.num_samps      = <num_samps>
stream_cmd.num_pulses     = <number_of_pulses_in_train>
stream_cmd.pulse_interval = <interval_between_pulses_in_sec>
stream_cmd.stream_now     = False
stream_cmd.time_spec      = <time_spec_of_first_pulse>

Alternatively, a list of pulse start times could be given.

Current queue length

If such a stream mode would be too hard to implement, can you implement a method of getting the current length of the command queue? Something like:

<number_of commands_in_queue>=replay.get_command_queue(<port>)

Setup Details

I'm using the X440 with the factory x4_400 fpga image flavor, through the python UHD package v4.6.0.0 (50fa3baa2) on Ubuntu 22.04. The interface is the standard RJ45 ethernet cable.

@mbr0wn
Copy link
Contributor

mbr0wn commented Sep 27, 2024

Hey @andsunds, this is a reasonable use case. Some comments and questions:

  • In your TX use case, are you transmitting the same pulse many times, or are you transmitting different types of pulses?
  • When receiving, is it an option to just receive, and drop samples in the software domain (or are you trying to reduce average data rates)?
  • When transmitting, same question. Can you generate a waveform that is silent between pulses, but you pre-generate the full waveform (i.e., pulse, zeros, pulse, zeros, and so on)?
  • I can see you're using the replay block (that's good). However, I'm curious if you need to use it the way you are. Again, do you really need to start/stop the receiver, or can you just grab all samples and then later discard some? (The answer may be yes, but I want to make sure we've covered all bases).

If you're tx/rx'ing 100ms worth of signal, that's really a small amount of data even at high rates (even at 2Gsps, that would be around 800MB out of our 4 GiB of onboard DRAM). So if you're using the replay block, you have plenty of space to capture the full pulse train without requiring start/stopping the radio.

Note that it's unlikely that we'll change the streaming API for this, at least, as long as we can't find an easy alternative route (that's because the streaming API is very basic by design, and works the same way across a bunch of devices).

@andsunds
Copy link
Author

Hi, thanks for the comments. In response to your questions:

  • We're transmitting the same pulse each time for now, but might want the flexibility to change waveform from pulse to pulse in the future. For now, however, we can stick with the same waveform each time.
  • It might be possible to receive pulses continuously, but some of our usecases will require captures over several "real-time seconds" on all 8 channels, so limiting the data rate by not recording the entire duration will be needed. (In this case, however, Tx will be handled by another backend.) Also, not all applications will be at the highest pulse repetition rate, the 10+ kHz was an example of the fastest rate we want to be able to use. We will likely want to Tx/Rx pulses at anywhere from ~100 Hz to ~10 kHz.
  • We have considered to zero-pad the waveform and simply loop the padded waveform from DRAM, but then we run into the problem that we need to turn off our power-amplifier during the zero padding. Currently, we're using the ATR_TX GPIO attribute to control our PA. The same goes for the Rx LNA, which ideally shouldn't be on at the same time as the PA.
  • This was the easiest way to get a usable GPIO interface for the PA/LNA, but I haven't looked into other ways of controlling the GPIO. The timing of the pulses (and GPIO control signals) is also critical. We cannot tolerate jitter in the start time of each pulse, which is why we're trying to run everything within the FPGA/RFNoC framework.

Hope this helps!

If it's of any value, we will also be running everything from the x440's onboard ARM processor as sort of stand-alone system.

@mbr0wn
Copy link
Contributor

mbr0wn commented Sep 27, 2024

Thanks, the comment on the ATR pins is good to know. It's possible to trigger those pins directly in a timed fashion, but I can't say off the top of my head if you then don't have the same issue when sending all the GPIO on/off commands.

If it's of any value, we will also be running everything from the x440's onboard ARM processor as sort of stand-alone system.

That should not be an issue in this case.

@mmatthebi
Copy link

Regarding this:

Interestingly I don't get an error message when I only issue the Rx command radio_chan_Rx.issue_stream_cmd(stream_cmd_Rx, 0), even though the recording has clearly stopped after the first ~32 pulses.

I believe that #817 proves that it just stops and there is no indication of error.

As a workaround for your use-case on the RX side: You might be able to write an RFNoC-Block similar to KeepOneInN, but one which keeps bursts of samples.

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

No branches or pull requests

3 participants