Hi Camille,

Sorry for the delay. I was out of town until today. I was able to take your
example and make it work for me. I used the same YAML as you, except I
changed firS to fir0. What UHD version are you using? You might consider
updating to the latest (v4.1.0.5) and recompiling your FPGA. I tested using
master.

One thing to note with the FIR filter is that you need to input extra
samples to get out all the data that you want. For example, you need to
request 101 packets in order to receive 100. In your example, you requested
1e6 samples. That should be enough for multiple packets, so I think that
should be fine. But just keep in mind that you won't get all the samples
you request.

Here's my version of your Python code with slight changes to set the
samples per packet (spp) and report the number of packets received. You
could try it to see if you get a different result with my changes.

##BEGIN######
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.40.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()

spp = 1920
num_packets = 500
radio_crtl.set_properties("spp=" + str(spp))

num_samps = spp*num_packets

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 or
{float(received_spls/spp)} packets')

if md.error_code != md.error_code.none:
    print(f'\033[1;31m[ERROR]\033[0m {md.strerror()}')
else:
    print(f'Everything went well.')

##END########


Thanks,

Wade

On Mon, Jan 17, 2022 at 9:41 AM Rob Kossler <rkoss...@nd.edu> wrote:

> 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