Discussion and technical support related to USRP, UHD, RFNoC
View all threadsHello all,
RxTx loopback is a feature that was missing(/hard to do) in RFNoC before at least 4.0.
Currently it works and there are even nice examples showing how set it up, so one doesn’t have to figure this out. There are examples both in pure UHD (https://github.com/EttusResearch/uhd/blob/master/host/examples/rfnoc_radio_loopback.cpp) and GNU Radio (https://github.com/gnuradio/gnuradio/blob/main/gr-uhd/examples/grc/rfnoc_radio_loopback.grc).
I’m trying to go one step forward and to add an RFNoC block to the loop-back on USRP X410. For simplicity I’m starting from the rfnoc-example (https://github.com/EttusResearch/uhd/tree/master/host/examples/rfnoc-example). The graph I want to get working looks like this: Radio#0==>DDC#0-->Gain#0-->DUC#1==>Radio#1.
I’ve build the rfnoc-example and I can confirm that it works with use of the example (https://github.com/EttusResearch/uhd/blob/master/host/examples/rfnoc-example/examples/rx_gain_estimate_power.py).
Then I tried to change the rfnoc_radio_loopback.cpp to connect Gain block between DDC and DUC.
In order to achieve that I changed this part (https://github.com/EttusResearch/uhd/blob/master/host/examples/rfnoc_radio_loopback.cpp#L123):
uhd::rfnoc::connect_through_blocks(
graph, rx_radio_ctrl_id, rx_chan, tx_radio_ctrl_id, tx_chan, skip_pp);
to:
uhd::rfnoc::block_id_t gain_block_id("0/Gain#0");
rfnoc::example::gain_block_control::sptr gain_control =
graph->get_blockrfnoc::example::gain_block_control(gain_block_id);
uhd::rfnoc::connect_through_blocks(
graph, rx_radio_ctrl_id, rx_chan, gain_block_id, 0, skip_pp);
uhd::rfnoc::connect_through_blocks(
graph, gain_block_id, 0, tx_radio_ctrl_id, tx_chan, skip_pp);
and later I added a call to function that sets the digital gain:
gain_control->set_gain_value(42);
Somehow I can’t get it working this way. The version without my change passes the signal. The version with it included doesn’t.
What might be wrong with this approach?
Best Regards,
Piotr Krysik
Hi Piotr,
from cursory reading this looks good to me. Things you could check:
if you have a fairly recent build from master, https://github.com/EttusResearch/uhd/commit/d3e27d94052110b180267907c8c12f3c2d050271 adds a dot style print of the graph to TRACE when the graph is committed so you can verify whether it looks as expected. If you don't have TRACE enabled you can just call to_dot from graph after commit and then render the resulting string.
[https://opengraph.githubassets.com/d65f8d77f90a59ad00f6ccbdb1a49b8c8269e1d4e43ee5e33e71785d99e293f4/EttusResearch/uhd/commit/d3e27d94052110b180267907c8c12f3c2d050271]https://github.com/EttusResearch/uhd/commit/d3e27d94052110b180267907c8c12f3c2d050271
host: add ability to query dot representation of graph · EttusResearch/uhd@d3e27d9https://github.com/EttusResearch/uhd/commit/d3e27d94052110b180267907c8c12f3c2d050271
Current implementation only support dot representation of the graph topology. This adds the ability to also query the current graph layout. The method prints out connected blocks (including streame...
github.com
Another thing that you can check is property propagation. Do radios and DDC/DUC have the expected rates?
Besides that, could you provide a log output of your example run?
Regards
Lars
[NI]https://www.ni.com/r/zf03uz
Lars Amsel
Principal Software Engineer
SW Discipline
+49351206931427tel:+49351206931427 | ni.comhttps://www.ni.com/
[National Instruments is now NI.]
INTERNAL - NI CONFIDENTIAL
From: perper@o2.pl perper@o2.pl
Sent: Wednesday, 12 June 2024 17:33
To: usrp-users@lists.ettus.com usrp-users@lists.ettus.com
Subject: [USRP-users] How to put additional RFNoC block in Rx-Tx loopback?
Hello all,
RxTx loopback is a feature that was missing(/hard to do) in RFNoC before at least 4.0.
Currently it works and there are even nice examples showing how set it up, so one doesn’t have to figure this out. There are examples both in pure UHD (https://github.com/EttusResearch/uhd/blob/master/host/examples/rfnoc_radio_loopback.cpp) and GNU Radio (https://github.com/gnuradio/gnuradio/blob/main/gr-uhd/examples/grc/rfnoc_radio_loopback.grc).
I’m trying to go one step forward and to add an RFNoC block to the loop-back on USRP X410. For simplicity I’m starting from the rfnoc-example (https://github.com/EttusResearch/uhd/tree/master/host/examples/rfnoc-example). The graph I want to get working looks like this: Radio#0==>DDC#0-->Gain#0-->DUC#1==>Radio#1.
I’ve build the rfnoc-example and I can confirm that it works with use of the example (https://github.com/EttusResearch/uhd/blob/master/host/examples/rfnoc-example/examples/rx_gain_estimate_power.py).
Then I tried to change the rfnoc_radio_loopback.cpp to connect Gain block between DDC and DUC.
In order to achieve that I changed this part (https://github.com/EttusResearch/uhd/blob/master/host/examples/rfnoc_radio_loopback.cpp#L123):
uhd::rfnoc::connect_through_blocks(
graph, rx_radio_ctrl_id, rx_chan, tx_radio_ctrl_id, tx_chan, skip_pp);
to:
uhd::rfnoc::block_id_t gain_block_id("0/Gain#0");
rfnoc::example::gain_block_control::sptr gain_control =
graph->get_blockrfnoc::example::gain_block_control(gain_block_id);
uhd::rfnoc::connect_through_blocks(
graph, rx_radio_ctrl_id, rx_chan, gain_block_id, 0, skip_pp);
uhd::rfnoc::connect_through_blocks(
graph, gain_block_id, 0, tx_radio_ctrl_id, tx_chan, skip_pp);
and later I added a call to function that sets the digital gain:
gain_control->set_gain_value(42);
Somehow I can’t get it working this way. The version without my change passes the signal. The version with it included doesn’t.
What might be wrong with this approach?
Best Regards,
Piotr Krysik
National Instruments Dresden GmbH; Geschäftsführer (Managing Directors): Sabrina Gilman, Kathleen Heard Spurck, Carl Schumacher; Sitz (Registered Office): Dresden; HRB (Commercial Register No.): 22081; Registergericht (Registration Court): Dresden
This email and any attachments are intended only for the person to whom this email is addressed and may contain confidential and/or privileged information. If you received this email in error, please do not disclose the contents to anyone, but notify the sender by return email and delete this email (and any attachments) from your system.
Hello Lars,
Thank you for the hint. The graph renders to the attached svg image and it looks as expected:
0/Radio#0:0==>0/DDC#0:0
0/DDC#0:0-->0/Gain#0:0
0/DUC#1:0==>0/Radio#1:0
0/Gain#0:0-->0/DUC#1:0
However regarding property propagation there are some warnings:
[TRACE] [RFNOC::GRAPH::DETAIL] Forwarding up to 22 edge properties from node 0/DDC#0 along forward edges.
[TRACE] [0/Gain#0] Incoming edge property: `tick_rate`, source info: OUTPUT_EDGE:0
[TRACE] [0/Gain#0] Incoming edge property: `mtu`, source info: OUTPUT_EDGE:0
[TRACE] [0/Gain#0] Incoming edge property: `samp_rate`, source info: OUTPUT_EDGE:0
[TRACE] [0/Gain#0] Received unknown incoming edge prop: samp_rate
[TRACE] [0/Gain#0] Incoming edge property: `scaling`, source info: OUTPUT_EDGE:0
[TRACE] [0/Gain#0] Skipped empty edge property: `scaling`, source info: OUTPUT_EDGE:0
[TRACE] [0/Gain#0] Incoming edge property: `type`, source info: OUTPUT_EDGE:0
[TRACE] [0/Gain#0] Received unknown incoming edge prop: type
[TRACE] [0/Gain#0] Incoming edge property: `atomic_item_size`, source info: OUTPUT_EDGE:0
[TRACE] [0/Gain#0] Received unknown incoming edge prop: atomic_item_size
This is the main difference in comparison to output of the program when DDC and DUC are connected directly without Gain block. Another one is that there are much more underflows (like 35 vs 2 when Gain block is not used in the loopback) + 1 overflow.
I’m attaching the log.
Also I attached also the yml used to build the image with gain block as this is something that was edited by me and not part of the rfnoc-example.
Best Regards,
Piotr Krysik
Hello all,
I found the reason of the problem and a solution that works for sample rate lower than master clock rate (245.76MHz by default for X410).
So the root cause of the issue is that clock used for processing in the ‘rfnoc_block_gain’ is ‘rfnoc_chdr’ clock (this is set in ‘gain.yml’). This clock has 200MHz by default for X410.
Taking into account that gain block processes one sample per clock cycle, rate of ‘rfnoc_chdr’ is too small to process whole stream of samples coming at the output of DDC block with decimation equal to 1.
Moreover in the ‘rfnoc_radio_loopback’ example ‘rate’ parameter is applied directly to radio rfnoc block and not to DDC. So no matter what is set there the decimation is always 1.
To make it work it was necessary to change the decimation to higher value by setting a proper rate with use of the set_output_rate function of the DDC block controller.
However I would like to make the example work even when there is no decimation. Therefore I tried to switch it to ‘ce’ which has rate 266.66(6)Mhz AFAIK by changing ‘control’ and ‘data’ clock domains in ‘gain.yml’ to ‘ce’. I changed also ‘noc_shell_gain.v’ and ‘rfnoc_block_gain.v’ by partially mimicking what I’ve seen in ‘moving_avg’ example. But probably I did something wrong as the design doesn’t pass timing check.
So the question is how to switch ‘rfnoc_block_gain’ example to use ‘ce’ clock instead of ‘rfnoc_chdr‘ and limit possibility of a mistake?
Best Regards,
Piotr Krysik
Hello,
I think I figured out what is wrong. It starts from the fact that ‘rfnoc_radio_loopback‘ example doesn’t change the decimation in the ‘DDC’ no matter what rate is selected. This is because ‘rate‘ parameter is applied to ‘Radio‘ RFNoC block. In the end the sample rate of the stream at the input of the ‘Gain‘ block is equal to ‘master_clock_rate’ (245.76MHz by default for X410).
However the ‘Gain‘ block uses ‘rfnoc_chdr‘ clock rate (200MHz for X410) both for control and the data. Taking into account that the ‘Gain’ clock processes one sample per clock cycle it is not able keep up with the input stream rate.
A workaround was to increase the decimation by setting proper rate with use of ‘set_output_rate’ function of DDC controller. After that the ‘Gain’ block started to work as expected.
However I need a ‘Gain’ block that is able to process samples coming with the maximum rate (without decimation). For this I’m trying to change the data clock to ‘ce’ (266.6(6) MHz for X410 AFAIK). I changed it to mimic i.e. what I ‘Moving_avg‘ has (so I changed ‘‘gain.yml’, ‘rfnoc_block_gain.v‘ and ‘noc_shell_gain.v’). But it doesn’t work yet.
So the question is: how to change the ‘Gain’ block so that it uses ‘ce’ clock instead of ‘rfnoc_chdr‘?
Best Regards,
Piotr Krysik
Sorry for repetition in the last post. I suppose my two previous posts went to moderation and there was no one to accept them during the Sunday?
I was able to connect ‘ce’ clock correctly. But changing the clock to the one that has chance of making the ‘gain.yml’ work with decimation=1 (in ‘DDC’ block) wasn’t the only reason it was not working.
So the question now is: what makes difference so that with decimation=1 set in the ‘DDC’ block there is no signal at the output of the ‘Gain‘ block (working in a Rx->Tx loopback) while with decimation>2 the signal passes through the ‘Gain‘ block as expected?
Best Regards,
Piotr Krysik
Ok. I know what was stopping the RFNoC flowgraph after correction of the clock. I was setting SPP (samples-per-packet) to a value that was somehow wrong for this case. After removing that command-line parameter, the loopback through ‘Gain’ block started to work.
I’m posting my changed ‘Gain’ block, that is clocked with ‘ce’ clock, in case anyone is interested.
Best Regards,
Piotr Krysik
Hi Piotr,
thanks a lot for posting your solution! We will need to go back and verify
that this example works on all USRPs, not just X310.
--M
On Mon, Jun 17, 2024 at 7:24 PM perper@o2.pl wrote:
Ok. I know what was stopping the RFNoC flowgraph after correction of the
clock. I was setting SPP (samples-per-packet) to a value that was somehow
wrong for this case. After removing that command-line parameter, the
loopback through ‘Gain’ block started to work.
I’m posting my changed ‘Gain’ block, that is clocked with ‘ce’ clock, in
case anyone is interested.
Best Regards,
Piotr Krysik
USRP-users mailing list -- usrp-users@lists.ettus.com
To unsubscribe send an email to usrp-users-leave@lists.ettus.com