A couple of comments: - this case is very similar to the Ettus example rfnoc_radio_loopback <https://github.com/EttusResearch/uhd/blob/master/host/examples/rfnoc_radio_loopback.cpp> which may be helpful to diagnose the problem - it seems in your calls to graph->connect(), the "is_back_edge" argument is set to true for all links. I think only one link (arbitrary) should be true - if you change your graph so that the Tx uses one radio and the Rx uses the other radio (rather than the same one in your example), does that connect OK? In this case you could set "is_back_edge" false for all links
Rob On Wed, Jun 3, 2026 at 10:09 AM niels.steffen.garibaldi--- via USRP-users < [email protected]> wrote: > Hi, > > Sorry, I am not an expert on the UHD Host driver, but since no one else > has answered I’ll give it a try. > > Looking at your Issue I have 2 thoughts. > > 1) Is there a specific reason/requirement you are using such an old UHD > version? > UHD 4.0 was released 5+ years ago and there have definitely been a lot of > improvements added since that version. > The current latest release is UHD 4.10, so the first thing I would > probably try to do is update the UHD version load the new bitfile to your > device and then see if this issue still occurs. > > 2) So in general you are correct. The UHD host driver has a representation > of the RFNoC graph on the host and when you configure one of the blocks, in > your case the DDC/DUC block, then the host driver checks if this setting > might effect any of the blocks that are connected to the block you are > configuring. > For that it checks the graph and goes through all of the graph edges and > propagates the property (change) to connected blocks. This is called > property propagation and it is done during the initialisation of the block > during session establishment and depending on the block it can also happen > every time you configure something of the block. > > In your case, changing the sample rate does effect the adjacent blocks. If > it works in Python but not in C++, that sounds like a race condition to me, > since a python application is comparably slower to execute than the C++ > application. Also the way that gnuradio establishes the session might be > slightly different. > > Also, it seems like your code between gnuradio and C++ is slightly > different: > In Python you are skipping the propagation with ` > self.rfnoc_graph.skip_propagation` but you are not skipping it for the > C++ graph connection. > Maybe you can try the other connect API function called > `connect_through_blocks` > <https://uhd.readthedocs.io/en/latest/namespaceuhd_1_1rfnoc.html#a8db0ee31f7409f7f4999c12b974f4c10> > which also has the option to skip propagation and see if that fixes your > C++ issues. > > Have you tried enabling debug/trace logs to get some more information > about what is actually happening inside of the UHD driver? > If not, I would recommend doing that to get a better idea when and where > the issue occurs. > > See https://kb.ettus.com/The_UHD_logging_facility for more information. > Depending on whether you are building your UHD host driver from source or > getting it via the package, you might only be able to set logging to debug. > > Sorry I could not be of more help. > > Regards, > Niels. > ------------------------------ > > > [email protected] wrote: > > Hi everyone, > > I'm trying to replicate a GNU Radio flowgraph and run it directly in UHD > 4.0 using C++, but I'm running into an issue that I can't solve. > > The Python/GNU Radio version works perfectly, but the equivalent C++ > implementation fails at runtime with the following error: > > RuntimeError: AccessError: Attempting to read property > `samp_rate@INPUT_EDGE:0' before it was initialized! > > I already tried configuring the DDC and DUC after the commit, but the > problem still persists and I don't understand why this property is not > being initialized correctly. > > The RFNoC graph topology is the following: > > 0/SEP#0:0==>0/DUC#0:0 > > | | * 0/DUC#0:0==>0/Radio#0:0 > > | | * 0/Radio#0:0==>0/DDC#0:0 > > | | * 0/DDC#0:0==>0/SEP#0:0 > > | | * 0/SEP#1:0==>0/DUC#0:1 > > | | * 0/SEP#4:0==>0/Block#0:0 > > | | * 0/Block#0:0==>0/SEP#4:0 > > From what I understand, the issue seems related to the propagation or > initialization order of the samp_rate property across the graph edges, but > I’m not sure which block is responsible or how GNU Radio handles this > internally compared to UHD C++. > > Below are the working GNU Radio/Python implementation and the failing UHD > C++ implementation: > > *Python / GNU Radio code (working)* > > # Blocks > > ################################################## > > self.ettus_rfnoc_tx_radio_0 = > ettus.rfnoc_tx_radio(self.rfnoc_graph, uhd.device_addr(''), > > -1, > > -1) > > self.ettus_rfnoc_tx_radio_0.set_rate(samp_rate) > > self.ettus_rfnoc_tx_radio_0.set_antenna('TX/RX', 0) > > > self.ettus_rfnoc_tx_radio_0.set_frequency(uhd.tune_request(center_freq_out, > ((samp_rate*0.5) + 2e6)), 0) > > self.ettus_rfnoc_tx_radio_0.set_gain(0, 0) > > self.ettus_rfnoc_tx_radio_0.set_bandwidth(samp_rate, 0) > > self.ettus_rfnoc_rx_radio_0 = ettus.rfnoc_rx_radio( > > self.rfnoc_graph, > > uhd.device_addr("spp=16"), > > -1, > > -1) > > self.ettus_rfnoc_rx_radio_0.set_rate(samp_rate) > > self.ettus_rfnoc_rx_radio_0.set_antenna('RX2', 0) > > self.ettus_rfnoc_rx_radio_0.set_frequency(center_freq_in, 0) > > self.ettus_rfnoc_rx_radio_0.set_gain(55, 0) > > self.ettus_rfnoc_rx_radio_0.set_agc(False, 0) > > self.ettus_rfnoc_rx_radio_0.set_bandwidth(samp_rate, 0) > > self.ettus_rfnoc_rx_radio_0.set_dc_offset(True, 0) > > self.ettus_rfnoc_rx_radio_0.set_iq_balance(True, 0) > > self.ettus_rfnoc_duc_0 = ettus.rfnoc_duc( > > self.rfnoc_graph, > > uhd.device_addr(''), > > -1, > > -1) > > self.ettus_rfnoc_duc_0.set_freq(0, 0) > > self.ettus_rfnoc_duc_0.set_input_rate(samp_rate, 0) > > self.ettus_rfnoc_ddc_0 = ettus.rfnoc_ddc( > > self.rfnoc_graph, > > uhd.device_addr(''), > > -1, > > -1) > > self.ettus_rfnoc_ddc_0.set_freq(0, 0) > > self.ettus_rfnoc_ddc_0.set_output_rate(samp_rate, 0) > > self.Filter_Passtaps_Filter_Passtaps_0 = > Filter_Passtaps.Filter_Passtaps( > > self.rfnoc_graph, > > uhd.device_addr(''), > > -1, > > -1) > > > self.Filter_Passtaps_Filter_Passtaps_0.set_int_property('user_reg', 0) > > > self.Filter_Passtaps_Filter_Passtaps_0.set_int_property('user1_reg', 66) > > > self.Filter_Passtaps_Filter_Passtaps_0.set_int_property('user2_reg', -2) > > > self.Filter_Passtaps_Filter_Passtaps_0.set_int_property('user3_reg', 0) > > > > > > ################################################## > > # Connections > > ################################################## > > > self.rfnoc_graph.connect(self.Filter_Passtaps_Filter_Passtaps_0.get_unique_id(), > 0, self.ettus_rfnoc_duc_0.get_unique_id(), 0, > self.rfnoc_graph.skip_propagation) > > self.rfnoc_graph.connect(self.ettus_rfnoc_ddc_0.get_unique_id(), > 0, self.Filter_Passtaps_Filter_Passtaps_0.get_unique_id(), 0, > self.rfnoc_graph.skip_propagation) > > self.rfnoc_graph.connect(self.ettus_rfnoc_duc_0.get_unique_id(), > 0, self.ettus_rfnoc_tx_radio_0.get_unique_id(), 0, > self.rfnoc_graph.skip_propagation) > > > self.rfnoc_graph.connect(self.ettus_rfnoc_rx_radio_0.get_unique_id(), 0, > self.ettus_rfnoc_ddc_0.get_unique_id(), 0, > self.rfnoc_graph.skip_propagation) > > *UHD C++ code (failing)* > > uhd::rfnoc::block_id_t rx_radio_id("0/Radio#0"); > > uhd::rfnoc::block_id_t tx_radio_id("0/Radio#0"); > > > > const size_t rx_chan = 0; // RX2 normalmente > > const size_t tx_chan = 0; // TX/RX normalmente > > > > uhd::rfnoc::block_id_t ddc_id("0/DDC#0"); > > uhd::rfnoc::block_id_t duc_id("0/DUC#0"); > > > > uhd::rfnoc::block_id_t filter_id("0/FilterPasstaps#0"); > > /********************************************************************** > > * GET BLOCK HANDLES > > *********************************************************************/ > > auto rx_radio = > graph->get_block<uhd::rfnoc::radio_control>(rx_radio_id); > > auto tx_radio = > graph->get_block<uhd::rfnoc::radio_control>(tx_radio_id); > > auto ddc = > graph->get_block<uhd::rfnoc::ddc_block_control>(ddc_id); > > auto duc = > graph->get_block<uhd::rfnoc::duc_block_control>(duc_id); > > auto filter = > graph->get_block<uhd::rfnoc::FilterPASStaps_block_ctrl>( filt_id ); > > > // Configurations Radio RX and TX, DUC and DDC. > > > > graph->connect(rx_radio_id, rx_chan, ddc_id, 0, true); > > graph->connect(ddc_id, 0, filter_id, 0, true); > > graph->connect(filter_id, 0, duc_id, 0, true); > > graph->connect(duc_id, 0, tx_radio_id, tx_chan, true); > > std::cout << "Commit graph..." << std::endl; > > graph->commit(); > > Has anyone encountered something similar or knows the correct > initialization/configuration order for RFNoC DUC/DDC blocks in UHD 4.0 C++? > > Any help would be greatly appreciated. > > Thanks in advance!! > > > _______________________________________________ > 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]
