usrp-users@lists.ettus.com

Discussion and technical support related to USRP, UHD, RFNoC

View all threads

Signal quality using RFNoC DUC blocks

C
carmixdev@gmail.com
Wed, May 7, 2025 4:13 PM

Hi, I’m developing a transmitter for a spread spectrum signal that has a bandwidth of 2MHz sampled at 6.26Msps on a X310+UBX160, I’ve tried to transmit it using standard method uhd.usrp.MultiUSRP(…) and it worked OK, the signal is received correctly and the receivers locks steadily to the signal.

Then I tried to do the same using RFNoCs  with the sequence:  SEP->DUC->RADIO.

The DUC is set for an input rate of 6.25MHz and an output rate of 200MHz.

The signal is transmitted, however in this second implementation the receiver doesn’t lock correctly on it. It seems like that the signal quality gets compromised.

Am I missing something?

Hi, I’m developing a transmitter for a spread spectrum signal that has a bandwidth of 2MHz sampled at 6.26Msps on a X310+UBX160, I’ve tried to transmit it using standard method uhd.usrp.MultiUSRP(…) and it worked OK, the signal is received correctly and the receivers locks steadily to the signal. Then I tried to do the same using RFNoCs with the sequence: SEP->DUC->RADIO. The DUC is set for an input rate of 6.25MHz and an output rate of 200MHz. The signal is transmitted, however in this second implementation the receiver doesn’t lock correctly on it. It seems like that the signal quality gets compromised. Am I missing something?
C
carmixdev@gmail.com
Thu, May 8, 2025 2:11 PM

Just to help in understanding what’s wrong with my code I attach here the two implementations, one with the multi usrp and the other with RFNoC. Reading the documentation I understand that the MultiUSRP stands on top of the RFNoC, so I think that it is only a problem of my implementation.

They should do the same thing, however in RFNoC implementation the receiver on the other side loses lock frequently.

Could someone help me understanding what’s wrong?

Just to help in understanding what’s wrong with my code I attach here the two implementations, one with the multi usrp and the other with RFNoC. Reading the documentation I understand that the MultiUSRP stands on top of the RFNoC, so I think that it is only a problem of my implementation. They should do the same thing, however in RFNoC implementation the receiver on the other side loses lock frequently. Could someone help me understanding what’s wrong?
C
carmixdev@gmail.com
Wed, May 14, 2025 8:19 PM

I discovered it myself, I wasn’t sending the tune_request_action to the system, but just setting the radio frequency through the radio_control block.

If you forget the tune request the radio will not fine tune to the desired frequency

It was not obvious and maybe I’m wrong but it seems not well documented( the unique clue that I found was the tune request on the replay example, but it was sent on the replay block)

I discovered it myself, I wasn’t sending the tune_request_action to the system, but just setting the radio frequency through the radio_control block. If you forget the tune request the radio will not fine tune to the desired frequency It was not obvious and maybe I’m wrong but it seems not well documented( the unique clue that I found was the tune request on the replay example, but it was sent on the replay block)
MB
Martin Braun
Tue, May 20, 2025 3:19 PM

Yeah this is a new-ish feature (sending tune requests through the graph).
Previously, you would have to set the frequency both on the radio block,
and then on the DUC block.

--M

On Wed, May 14, 2025 at 10:21 PM carmixdev@gmail.com wrote:

I discovered it myself, I wasn’t sending the tune_request_action to the
system, but just setting the radio frequency through the radio_control
block.

If you forget the tune request the radio will not fine tune to the desired
frequency

It was not obvious and maybe I’m wrong but it seems not well documented(
the unique clue that I found was the tune request on the replay example,
but it was sent on the replay block)


USRP-users mailing list -- usrp-users@lists.ettus.com
To unsubscribe send an email to usrp-users-leave@lists.ettus.com

Yeah this is a new-ish feature (sending tune requests through the graph). Previously, you would have to set the frequency both on the radio block, and then on the DUC block. --M On Wed, May 14, 2025 at 10:21 PM <carmixdev@gmail.com> wrote: > I discovered it myself, I wasn’t sending the tune_request_action to the > system, but just setting the radio frequency through the radio_control > block. > > If you forget the tune request the radio will not fine tune to the desired > frequency > > It was not obvious and maybe I’m wrong but it seems not well documented( > the unique clue that I found was the tune request on the replay example, > but it was sent on the replay block) > _______________________________________________ > USRP-users mailing list -- usrp-users@lists.ettus.com > To unsubscribe send an email to usrp-users-leave@lists.ettus.com >
C
carmixdev@gmail.com
Tue, May 20, 2025 9:10 PM

Where can I find more info about the fine frequency tuning?

In a more complex example where I need to set offset frequencies in a multichannel DUC what is the correct sequence to keep the fine tuning?

Ty

C

Where can I find more info about the fine frequency tuning? In a more complex example where I need to set offset frequencies in a multichannel DUC what is the correct sequence to keep the fine tuning? Ty C
RK
Rob Kossler
Tue, May 20, 2025 9:26 PM

Have you seen these topics in the manual?
tuning notes
https://files.ettus.com/manual/page_general.html#general_tuning
synchronizing phase
https://files.ettus.com/manual/page_sync.html#sync_phase

On Tue, May 20, 2025 at 5:10 PM carmixdev@gmail.com wrote:

Where can I find more info about the fine frequency tuning?

In a more complex example where I need to set offset frequencies in a
multichannel DUC what is the correct sequence to keep the fine tuning?

Ty

C


USRP-users mailing list -- usrp-users@lists.ettus.com
To unsubscribe send an email to usrp-users-leave@lists.ettus.com

Have you seen these topics in the manual? tuning notes <https://files.ettus.com/manual/page_general.html#general_tuning> synchronizing phase <https://files.ettus.com/manual/page_sync.html#sync_phase> On Tue, May 20, 2025 at 5:10 PM <carmixdev@gmail.com> wrote: > Where can I find more info about the fine frequency tuning? > > In a more complex example where I need to set offset frequencies in a > multichannel DUC what is the correct sequence to keep the fine tuning? > > Ty > > > C > _______________________________________________ > USRP-users mailing list -- usrp-users@lists.ettus.com > To unsubscribe send an email to usrp-users-leave@lists.ettus.com >
MB
Martin Braun
Wed, May 21, 2025 7:01 AM

There's not much to it, really. If you have a multichannel DUC setup, my
guess is you have a single LO frequency?

In that case, the only thing you need is the set_freq() API call:
https://uhd.readthedocs.io/en/latest/classuhd_1_1rfnoc_1_1duc__block__control.html#a0b5f86857c24d0b162fec528272c2024

...it has a built-in command-time argument, so it saves you the additional
call to set_command_time().

--M

On Tue, May 20, 2025 at 11:10 PM carmixdev@gmail.com wrote:

Where can I find more info about the fine frequency tuning?

In a more complex example where I need to set offset frequencies in a
multichannel DUC what is the correct sequence to keep the fine tuning?

Ty

C


USRP-users mailing list -- usrp-users@lists.ettus.com
To unsubscribe send an email to usrp-users-leave@lists.ettus.com

There's not much to it, really. If you have a multichannel DUC setup, my guess is you have a single LO frequency? In that case, the only thing you need is the set_freq() API call: https://uhd.readthedocs.io/en/latest/classuhd_1_1rfnoc_1_1duc__block__control.html#a0b5f86857c24d0b162fec528272c2024 ...it has a built-in command-time argument, so it saves you the additional call to set_command_time(). --M On Tue, May 20, 2025 at 11:10 PM <carmixdev@gmail.com> wrote: > Where can I find more info about the fine frequency tuning? > > In a more complex example where I need to set offset frequencies in a > multichannel DUC what is the correct sequence to keep the fine tuning? > > Ty > > > C > _______________________________________________ > USRP-users mailing list -- usrp-users@lists.ettus.com > To unsubscribe send an email to usrp-users-leave@lists.ettus.com >
C
carmixdev@gmail.com
Wed, May 21, 2025 2:44 PM

Yes Martin, for example I’m working on a X310+UBX160 with a multichannel DUC that has 4 inputs each one with a different frequency offset and then i sum the outputs with the addsub rfnoc block(I generated the FPGA firmware accordingly).

Actually I managed to have it work correctly but I had to discover by myself some oddities, the correct steps in my configuration are in order:

1-configure the graph according to my needs (radio_control, duc, streamer)

2-set the RF output frequency on the radio control

3-make the tune request through the streamer

4-set the desired frequency offset on the DUC (for example: -10e6, -5e6, 5e6, 10e6)

The last step is the more critical, in order to get the exact offset I had first to get the starting frequency offset of the DUC (which is not zero after the tune request, but just on the first channel of the DUC!!!) and then to sum up that residual frequency offset (which actually counts few kHz) to the desired frequency offset.

If I miss this step it won’t have the exact offset needed.

It seems to me a bit clumsy, is there a cleaner way to do it?

Yes Martin, for example I’m working on a X310+UBX160 with a multichannel DUC that has 4 inputs each one with a different frequency offset and then i sum the outputs with the addsub rfnoc block(I generated the FPGA firmware accordingly). Actually I managed to have it work correctly but I had to discover by myself some oddities, the correct steps in my configuration are in order: 1-configure the graph according to my needs (radio_control, duc, streamer) 2-set the RF output frequency on the radio control 3-make the tune request through the streamer 4-set the desired frequency offset on the DUC (for example: -10e6, -5e6, 5e6, 10e6) The last step is the more critical, in order to get the exact offset I had first to get the starting frequency offset of the DUC (which is not zero after the tune request, but just on the first channel of the DUC!!!) and then to sum up that residual frequency offset (which actually counts few kHz) to the desired frequency offset. If I miss this step it won’t have the exact offset needed. It seems to me a bit clumsy, is there a cleaner way to do it?
RK
Rob Kossler
Wed, May 21, 2025 8:08 PM

I think that some of the convenience mechanisms that you might see in the
examples (such as passing a tune request through the streamer) are likely
only helpful in a "typical" graph. In your graph with 4 DUC ports connected
to 1 Radio port with AddSub blocks to add the 4 DUC ports together, it is
not a 1-to-1 relationship between DUC and Radio.

It seems to me that your step 3 below is not needed or helpful.  It seems
you could set the LO frequency via the Radio block.  But, this will be
quantized and not necessarily at the exact frequency you request. Thus, if
it is important to get the right frequency, you will need to use the return
value from the radio->set_tx_frequency function to determine your
quantization error.  Then, you can call duc->set_freq for your DUC ports
with a frequency argument that includes both your desired values of -10,
-5, 5, 10 MHz as well as the quantization error you determined setting the
LO.
Rob

On Wed, May 21, 2025 at 10:45 AM carmixdev@gmail.com wrote:

Yes Martin, for example I’m working on a X310+UBX160 with a multichannel
DUC that has 4 inputs each one with a different frequency offset and then i
sum the outputs with the addsub rfnoc block(I generated the FPGA firmware
accordingly).

Actually I managed to have it work correctly but I had to discover by
myself some oddities, the correct steps in my configuration are in order:

1-configure the graph according to my needs (radio_control, duc, streamer)

2-set the RF output frequency on the radio control

3-make the tune request through the streamer

4-set the desired frequency offset on the DUC (for example: -10e6, -5e6,
5e6, 10e6)

The last step is the more critical, in order to get the exact offset I had
first to get the starting frequency offset of the DUC (which is not zero
after the tune request, but just on the first channel of the DUC!!!) and
then to sum up that residual frequency offset (which actually counts few
kHz) to the desired frequency offset.

If I miss this step it won’t have the exact offset needed.

It seems to me a bit clumsy, is there a cleaner way to do it?


USRP-users mailing list -- usrp-users@lists.ettus.com
To unsubscribe send an email to usrp-users-leave@lists.ettus.com

I think that some of the convenience mechanisms that you might see in the examples (such as passing a tune request through the streamer) are likely only helpful in a "typical" graph. In your graph with 4 DUC ports connected to 1 Radio port with AddSub blocks to add the 4 DUC ports together, it is not a 1-to-1 relationship between DUC and Radio. It seems to me that your step 3 below is not needed or helpful. It seems you could set the LO frequency via the Radio block. But, this will be quantized and not necessarily at the exact frequency you request. Thus, if it is important to get the right frequency, you will need to use the return value from the radio->set_tx_frequency function to determine your quantization error. Then, you can call duc->set_freq for your DUC ports with a frequency argument that includes both your desired values of -10, -5, 5, 10 MHz as well as the quantization error you determined setting the LO. Rob On Wed, May 21, 2025 at 10:45 AM <carmixdev@gmail.com> wrote: > Yes Martin, for example I’m working on a X310+UBX160 with a multichannel > DUC that has 4 inputs each one with a different frequency offset and then i > sum the outputs with the addsub rfnoc block(I generated the FPGA firmware > accordingly). > > Actually I managed to have it work correctly but I had to discover by > myself some oddities, the correct steps in my configuration are in order: > > 1-configure the graph according to my needs (radio_control, duc, streamer) > > 2-set the RF output frequency on the radio control > > 3-make the tune request through the streamer > > 4-set the desired frequency offset on the DUC (for example: -10e6, -5e6, > 5e6, 10e6) > > The last step is the more critical, in order to get the exact offset I had > first to get the starting frequency offset of the DUC (which is not zero > after the tune request, but just on the first channel of the DUC!!!) and > then to sum up that residual frequency offset (which actually counts few > kHz) to the desired frequency offset. > > If I miss this step it won’t have the exact offset needed. > > It seems to me a bit clumsy, is there a cleaner way to do it? > _______________________________________________ > USRP-users mailing list -- usrp-users@lists.ettus.com > To unsubscribe send an email to usrp-users-leave@lists.ettus.com >
MB
Martin Braun
Thu, May 22, 2025 7:43 AM

Agree with Rob here. The purpose of the tune request to the graph is to
avoid both steps 2  and 4 and replace it with something more familiar to
people coming from the multi_usrp world.

Maybe a general comment on the RFNoC API is useful here: With RFNoC, you
get a much more fine-grained control over all components in your system
(and most importantly, you can choose those components yourself). However,
the flip side is that you lose some of the convenience functions that you
can offer if you're using the multi_usrp API.

At the risk of sounding defensive, in your case, you have 5 components with
configurable frequencies that you need to set: One radio (controlling the
LO frequency), and 4 DUCs (with digital frequency shifters). That
translates into exactly 5 API calls to set each frequency. Because you have
a special type of application (four DUC outputs summed into one RF input),
it is not something that the RFNoC API can auto-magically set up for you.
Or to put it differently, if you want an API call that auto-sets all 5
frequencies at the same time, then you need to provide that logic yourself,
the same way that UHD provides logic to convert a tune request into a
digital (DUC/DDC) tune, and an analog tune (LO). But the RFNoC API provides
exactly the APIs to set your 5 different frequencies to 5 different
components in 5 API calls -- that seems reasonable to me.

--M

On Wed, May 21, 2025 at 10:08 PM Rob Kossler via USRP-users <
usrp-users@lists.ettus.com> wrote:

I think that some of the convenience mechanisms that you might see in the
examples (such as passing a tune request through the streamer) are likely
only helpful in a "typical" graph. In your graph with 4 DUC ports connected
to 1 Radio port with AddSub blocks to add the 4 DUC ports together, it is
not a 1-to-1 relationship between DUC and Radio.

It seems to me that your step 3 below is not needed or helpful.  It seems
you could set the LO frequency via the Radio block.  But, this will be
quantized and not necessarily at the exact frequency you request. Thus, if
it is important to get the right frequency, you will need to use the return
value from the radio->set_tx_frequency function to determine your
quantization error.  Then, you can call duc->set_freq for your DUC ports
with a frequency argument that includes both your desired values of -10,
-5, 5, 10 MHz as well as the quantization error you determined setting the
LO.
Rob

On Wed, May 21, 2025 at 10:45 AM carmixdev@gmail.com wrote:

Yes Martin, for example I’m working on a X310+UBX160 with a multichannel
DUC that has 4 inputs each one with a different frequency offset and then i
sum the outputs with the addsub rfnoc block(I generated the FPGA firmware
accordingly).

Actually I managed to have it work correctly but I had to discover by
myself some oddities, the correct steps in my configuration are in order:

1-configure the graph according to my needs (radio_control, duc, streamer)

2-set the RF output frequency on the radio control

3-make the tune request through the streamer

4-set the desired frequency offset on the DUC (for example: -10e6, -5e6,
5e6, 10e6)

The last step is the more critical, in order to get the exact offset I
had first to get the starting frequency offset of the DUC (which is not
zero after the tune request, but just on the first channel of the DUC!!!)
and then to sum up that residual frequency offset (which actually counts
few kHz) to the desired frequency offset.

If I miss this step it won’t have the exact offset needed.

It seems to me a bit clumsy, is there a cleaner way to do it?


USRP-users mailing list -- usrp-users@lists.ettus.com
To unsubscribe send an email to usrp-users-leave@lists.ettus.com


USRP-users mailing list -- usrp-users@lists.ettus.com
To unsubscribe send an email to usrp-users-leave@lists.ettus.com

Agree with Rob here. The purpose of the tune request to the graph is to avoid both steps 2 and 4 and replace it with something more familiar to people coming from the multi_usrp world. Maybe a general comment on the RFNoC API is useful here: With RFNoC, you get a much more fine-grained control over all components in your system (and most importantly, you can choose those components yourself). However, the flip side is that you lose some of the convenience functions that you can offer if you're using the multi_usrp API. At the risk of sounding defensive, in your case, you have 5 components with configurable frequencies that you need to set: One radio (controlling the LO frequency), and 4 DUCs (with digital frequency shifters). That translates into exactly 5 API calls to set each frequency. Because you have a special type of application (four DUC outputs summed into one RF input), it is not something that the RFNoC API can auto-magically set up for you. Or to put it differently, if you want an API call that auto-sets all 5 frequencies at the same time, then you need to provide that logic yourself, the same way that UHD provides logic to convert a tune request into a digital (DUC/DDC) tune, and an analog tune (LO). But the RFNoC API provides exactly the APIs to set your 5 different frequencies to 5 different components in 5 API calls -- that seems reasonable to me. --M On Wed, May 21, 2025 at 10:08 PM Rob Kossler via USRP-users < usrp-users@lists.ettus.com> wrote: > I think that some of the convenience mechanisms that you might see in the > examples (such as passing a tune request through the streamer) are likely > only helpful in a "typical" graph. In your graph with 4 DUC ports connected > to 1 Radio port with AddSub blocks to add the 4 DUC ports together, it is > not a 1-to-1 relationship between DUC and Radio. > > It seems to me that your step 3 below is not needed or helpful. It seems > you could set the LO frequency via the Radio block. But, this will be > quantized and not necessarily at the exact frequency you request. Thus, if > it is important to get the right frequency, you will need to use the return > value from the radio->set_tx_frequency function to determine your > quantization error. Then, you can call duc->set_freq for your DUC ports > with a frequency argument that includes both your desired values of -10, > -5, 5, 10 MHz as well as the quantization error you determined setting the > LO. > Rob > > On Wed, May 21, 2025 at 10:45 AM <carmixdev@gmail.com> wrote: > >> Yes Martin, for example I’m working on a X310+UBX160 with a multichannel >> DUC that has 4 inputs each one with a different frequency offset and then i >> sum the outputs with the addsub rfnoc block(I generated the FPGA firmware >> accordingly). >> >> Actually I managed to have it work correctly but I had to discover by >> myself some oddities, the correct steps in my configuration are in order: >> >> 1-configure the graph according to my needs (radio_control, duc, streamer) >> >> 2-set the RF output frequency on the radio control >> >> 3-make the tune request through the streamer >> >> 4-set the desired frequency offset on the DUC (for example: -10e6, -5e6, >> 5e6, 10e6) >> >> The last step is the more critical, in order to get the exact offset I >> had first to get the starting frequency offset of the DUC (which is not >> zero after the tune request, but just on the first channel of the DUC!!!) >> and then to sum up that residual frequency offset (which actually counts >> few kHz) to the desired frequency offset. >> >> If I miss this step it won’t have the exact offset needed. >> >> It seems to me a bit clumsy, is there a cleaner way to do it? >> _______________________________________________ >> USRP-users mailing list -- usrp-users@lists.ettus.com >> To unsubscribe send an email to usrp-users-leave@lists.ettus.com >> > _______________________________________________ > USRP-users mailing list -- usrp-users@lists.ettus.com > To unsubscribe send an email to usrp-users-leave@lists.ettus.com >