Hi Camille,
The stock example rfnoc_rx_to_file might be helpful. This example allows
you to run an Rx-only path with the FIR block inserted. Note that this
example was just recently fixed for UHD 4.x so you will need to be using a
recent version of UHD.  This would allow you to test your FPGA with a
"known good" UHD program. Also, if you were to rebuild your FPGA with an
SEP dedicated to your FIR block, you would then be able to run either with
or without the FIR block. In fact, you could even create an FIR-only RFNoC
graph to stream from the host to your block and back to the host (ignoring
the radio and DDC).  This would require a simple UHD or Python program
though - I wish Ettus included a stock example of this since it is a very
useful test case.
Rob

On Mon, Jan 17, 2022 at 9:52 AM Camille Moniere <camille.moni...@univ-ubs.fr>
wrote:

> Hello,
>
> Is there any new idea on the topic? Is this a bug in the fir_filter RFNoC
> block? I haven't found a way to make it work yet...
>
> Camille.
>
> On 1/14/22 10:41, Camille Moniere wrote:
>
> Just a typo, I used firS in the file, and I change the first occurrence
> while pasting the file, considering my use of fir0 in my
> explanations.
> There it is, with only fir0 (even if it does not change the initial
> issue):
>
> # General parameters
> # -----------------------------------------
> schema: rfnoc_imagebuilder_args # Identifier for the schema used to
> validate this file
> copyright: 'Camille Monière' # Copyright information used in file headers
> license: 'SPDX-License-Identifier: LGPL-3.0-or-later' # License
> information used in file headers
> version: '1.0' # File version
> rfnoc_version: '1.0' # RFNoC protocol version
> chdr_width: 64 # Bit width of the CHDR bus for this image
> device: 'x310'
> default_target: 'X310_HG'
> # A list of all stream endpoints in design
> # ----------------------------------------
> stream_endpoints:
> ep0: # Stream endpoint name
> ctrl: True # Endpoint passes control traffic
> data: True # Endpoint passes data traffic
> buff_size: 0 # Ingress buffer size for data
> # A list of all NoC blocks in design
> # ----------------------------------
> noc_blocks:
> ddc0:
> block_desc: 'ddc.yml'
> parameters:
> NUM_PORTS: 1
> radio0:
> block_desc: 'radio_2x64.yml'
> parameters:
> NUM_PORTS: 1
> fir0:
> block_desc: 'fir_filter.yml'
> parameters:
> NUM_PORTS: 1
> COEFF_WIDTH: 16
> NUM_COEFFS: 21
> COEFFS_VEC: "{ 16'h7FFF, {320{1'b0}} }"
> RELOADABLE_COEFFS: 1
> SYMMETRIC_COEFFS: 0
> SKIP_ZERO_COEFFS: 0
> USE_EMBEDDED_REGS_COEFFS: 1
> # A list of all static connections in design
> # ------------------------------------------
> # Format: A list of connection maps (list of key-value pairs) with the
> following keys
> # - srcblk = Source block to connect
> # - srcport = Port on the source block to connect
> # - dstblk = Destination block to connect
> # - dstport = Port on the destination block to connect
> connections:
> # radio0 to ep0 - RFA RX
> - { srcblk: radio0, srcport: out_0, dstblk: ddc0, dstport: in_0 }
> - { srcblk: ddc0, srcport: out_0, dstblk: fir0, dstport: in_0 }
> - { srcblk: fir0, srcport: out_0, dstblk: ep0, dstport: in0 }
> # BSP Connections
> - { srcblk: radio0, srcport: ctrl_port, dstblk: _device_, dstport:
> ctrlport_radio0 }
> - { srcblk: _device_, srcport: x300_radio0, dstblk: radio0, dstport:
> x300_radio }
> - { srcblk: _device_, srcport: time_keeper, dstblk: radio0, dstport:
> time_keeper }
> # A list of all clock domain connections in design
> # ------------------------------------------
> # Format: A list of connection maps (list of key-value pairs) with the
> following keys
> # - srcblk = Source block to connect (Always "_device"_)
> # - srcport = Clock domain on the source block to connect
> # - dstblk = Destination block to connect
> # - dstport = Clock domain on the destination block to connect
> clk_domains:
> - { srcblk: _device_, srcport: radio, dstblk: radio0, dstport: radio }
> - { srcblk: _device_, srcport: ce, dstblk: ddc0, dstport: ce }
> - { srcblk: _device_, srcport: ce, dstblk: fir0, dstport: ce }
>
> On 1/13/22 18:30, Wade Fife wrote:
>
> At a glance, the YML has both firS and fir0. I was expecting just fir0.
> But I also would have expected rfnoc_image_builder to throw an error for
> that.
>
> Wade
>
> On Thu, Jan 13, 2022 at 11:19 AM Camille Moniere <
> camille.moni...@univ-ubs.fr> wrote:
>
>> Hi wade,
>>
>> I had already linked the FIR ce to the ce of the _device_.
>>
>> Also, this custom image aims only to receive data (so no duc nor SEP for
>> TX). I tried to free some space, considering only one UBX-160 is available
>> (so only 1 radio).
>> I have read in the RFNoC guide that, for a device to host communication,
>> an ingress buffer of size 0 is possible, again to free resources.
>> A big block is expected to be added in the future...
>>
>> Here the YAML file I use with rfnoc_image_builder:
>>
>> # General parameters
>> # -----------------------------------------
>> schema: rfnoc_imagebuilder_args # Identifier for the schema used to
>> validate this file
>> copyright: 'Camille Monière' # Copyright information used in file headers
>> license: 'SPDX-License-Identifier: LGPL-3.0-or-later' # License
>> information used in file headers
>> version: '1.0' # File version
>> rfnoc_version: '1.0' # RFNoC protocol version
>> chdr_width: 64 # Bit width of the CHDR bus for this image
>> device: 'x310'
>> default_target: 'X310_HG'
>> # A list of all stream endpoints in design
>> # ----------------------------------------
>> stream_endpoints:
>> ep0: # Stream endpoint name
>> ctrl: True # Endpoint passes control traffic
>> data: True # Endpoint passes data traffic
>> buff_size: 0 # Ingress buffer size for data
>> # A list of all NoC blocks in design
>> # ----------------------------------
>> noc_blocks:
>> ddc0:
>> block_desc: 'ddc.yml'
>> parameters:
>> NUM_PORTS: 1
>> radio0:
>> block_desc: 'radio_2x64.yml'
>> parameters:
>> NUM_PORTS: 1
>> fir0:
>> block_desc: 'fir_filter.yml'
>> parameters:
>> NUM_PORTS: 1
>> COEFF_WIDTH: 16
>> NUM_COEFFS: 21
>> COEFFS_VEC: "{ 16'h7FFF, {320{1'b0}} }"
>> RELOADABLE_COEFFS: 1
>> SYMMETRIC_COEFFS: 0
>> SKIP_ZERO_COEFFS: 0
>> USE_EMBEDDED_REGS_COEFFS: 1
>> # A list of all static connections in design
>> # ------------------------------------------
>> # Format: A list of connection maps (list of key-value pairs) with the
>> following keys
>> # - srcblk = Source block to connect
>> # - srcport = Port on the source block to connect
>> # - dstblk = Destination block to connect
>> # - dstport = Port on the destination block to connect
>> connections:
>> # radio0 to ep0 - RFA RX
>> - { srcblk: radio0, srcport: out_0, dstblk: ddc0, dstport: in_0 }
>> - { srcblk: ddc0, srcport: out_0, dstblk: firS, dstport: in_0 }
>> - { srcblk: firS, srcport: out_0, dstblk: ep0, dstport: in0 }
>> # BSP Connections
>> - { srcblk: radio0, srcport: ctrl_port, dstblk: _device_, dstport:
>> ctrlport_radio0 }
>> - { srcblk: _device_, srcport: x300_radio0, dstblk: radio0, dstport:
>> x300_radio }
>> - { srcblk: _device_, srcport: time_keeper, dstblk: radio0, dstport:
>> time_keeper }
>> # A list of all clock domain connections in design
>> # ------------------------------------------
>> # Format: A list of connection maps (list of key-value pairs) with the
>> following keys
>> # - srcblk = Source block to connect (Always "_device"_)
>> # - srcport = Clock domain on the source block to connect
>> # - dstblk = Destination block to connect
>> # - dstport = Clock domain on the destination block to connect
>> clk_domains:
>> - { srcblk: _device_, srcport: radio, dstblk: radio0, dstport: radio }
>> - { srcblk: _device_, srcport: ce, dstblk: ddc0, dstport: ce }
>> - { srcblk: _device_, srcport: ce, dstblk: firS, dstport: ce }
>>
>>
>> I have tried in python and in C++, with UHD and directly with RFNoC API.
>> None succeeded
>> For instance, this is what I do in Python:
>>
>> import numpy as np
>> import scipy as sp
>> import ipywidgets as widgets
>> import matplotlib.pyplot as plt
>> import uhd
>> graph = uhd.rfnoc.RfnocGraph("addr=192.168.10.2,dboard_clock_rate=20e6")
>> radio_crtl = uhd.rfnoc.RadioControl(graph.get_block("0/Radio#0"))
>> ddc_crtl = uhd.rfnoc.DdcBlockControl(graph.get_block("0/DDC#0"))
>> target_freq = 433e6
>> target_gain = 25
>> target_rate = 1e6
>> radio_crtl.set_rx_antenna('RX2', 0)
>> radio_crtl.get_rx_antenna(0)
>> actual_gain = radio_crtl.set_rx_gain(target_gain, 0)
>> actual_rf_freq = radio_crtl.set_rx_frequency(target_freq, 0)
>> target_dsp_freq = actual_rf_freq - target_freq
>> actual_dsp_freq = ddc_crtl.set_freq(target_dsp_freq, 0)
>> clipped_rx_freq = actual_rf_freq - actual_dsp_freq
>> actual_rate = ddc_crtl.set_output_rate(target_rate, 0)
>> fir_static = uhd.rfnoc.FirFilterBlockControl(graph.get_block("0/FIR#0"))
>> coefficients = fir_static.get_coefficients()
>> fir_static.set_coefficients(coefficients)
>> coefficients = fir_static.get_coefficients()
>> plt.stem(coefficients)
>> plt.show()
>> stream_args = uhd.usrp.StreamArgs("fc32", "sc16")
>> recv_stream = graph.create_rx_streamer(1, stream_args)
>> graph.connect(radio_crtl.get_block_id(), 0, ddc_crtl.get_block_id(), 0,
>> False)
>> graph.connect(ddc_crtl.get_block_id(), 0, fir_static.get_block_id(), 0,
>> False)
>> graph.connect(fir_static.get_block_id(), 0, recv_stream, 0)
>> graph.commit()
>> num_samps = int(1e6) # 1 MB of data, be aware.
>> data = np.empty((num_samps), dtype=np.complex64)
>> md = uhd.types.RXMetadata()
>> stream_cmd = uhd.types.StreamCMD(uhd.types.StreamMode.num_done)
>> stream_cmd.stream_now = True
>> stream_cmd.num_samps = num_samps
>> stream_cmd.time_spec = uhd.types.TimeSpec(1, 0) # Wait 1s before
>> reception
>> recv_stream.issue_stream_cmd(stream_cmd)
>> received_spls = recv_stream.recv(data, md, 3.)
>> print(f'Received {float(received_spls):.2e} samples')
>> if md.error_code != md.error_code.none:
>> print(f'\033[1;31m[ERROR]\033[0m {md.strerror()}')
>> else:
>> print(f'Everything went well.')
>>
>> Without the Fir (and adapting the code of course), I get my 1e6 data
>> buffer.
>>
>> Is there an error I miss, or have I made too much space, deleting
>> important part in the process?
>>
>> On 1/13/22 17:08, Wade Fife wrote:
>>
>> In particular, make sure you have a clock connected to the CE input of
>> the FIR filter. Something like this in your clk_domains section:
>>
>> clk_domains:
>>     - { srcblk: _device_, srcport: ce, dstblk: fir0, dstport: ce }
>>
>> Wade
>>
>> On Thu, Jan 13, 2022 at 10:04 AM Wade Fife <wade.f...@ettus.com> wrote:
>>
>>> Hi Camille,
>>>
>>> Maybe you could share your RFNoC YML file and someone could take a look?
>>> There might be something wrong there.
>>>
>>> Wade
>>>
>>> On Thu, Jan 13, 2022 at 8:32 AM Camille Moniere <
>>> camille.moni...@univ-ubs.fr> wrote:
>>>
>>>> Hello everyone,
>>>>
>>>> I unsuccessfully try to use the FIR Filter RFNoC block in reception,
>>>> in
>>>> an USRP X310 with a UBX-160 daughterboard on-board.
>>>> I have tested several topology for the custom image (radio0 - > ddc0
>>>> ->
>>>> fir0 -> ep0 || radio0 -> ddc0 -> ep0 + ep1 -> fir0 + fir0 -> ep1, for
>>>> example),
>>>> with several parameter for the filter (With or without re-loadable
>>>> coefficients, with or without embedded DSP registers, 21 coef' instead
>>>> of 41 ...) but it ultimately
>>>> always fails the same way.
>>>> When the FIR is used, I can't retrieve any data. I got an Overflow
>>>> error, without receiving any samples. Sometimes, I even got a "Late
>>>> Command" error, even when using  RFNoC in C++
>>>> (graph committed immediately before the stream now stream_cmd).
>>>>
>>>> For the record, the center frequency is 433 MHz for a sampling rate of
>>>> 1
>>>> Msps.
>>>>
>>>> I assumed the filter output one complex sample (sc16) for each new
>>>> input
>>>> (sc16 too). Am I wrong? Or is there specific setup I have forgotten?
>>>> Has someone successfully used this block, and can provide an example
>>>> or
>>>> tutorial?
>>>>
>>>> Regards,
>>>>
>>>> Camille
>>>> _______________________________________________
>>>> USRP-users mailing list -- usrp-users@lists.ettus.com
>>>> To unsubscribe send an email to usrp-users-le...@lists.ettus.com
>>>>
>>>
>>
>
> _______________________________________________
> USRP-users mailing list -- usrp-users@lists.ettus.com
> To unsubscribe send an email to usrp-users-le...@lists.ettus.com
>
_______________________________________________
USRP-users mailing list -- usrp-users@lists.ettus.com
To unsubscribe send an email to usrp-users-le...@lists.ettus.com

Reply via email to