AL
Andrew Lanez
Tue, Aug 8, 2017 9:56 AM
Hi,
I am developing a FIR filter that will eventually accepts complex taps
reprogrammable during runtime. As a first iteration, I want to verify it
works like the in-tree module with int_vector real taps. So I configure the
settings register in OOT module's .xml file to take int_vector taps but
running it returns:
RuntimeError: RuntimeError: not yet implemented: int_vector
I guess it's because the in-tree module's ettus.rfnoc_fir_cci() make
function supports int_vector whereas my rfnocmodtool generated make
function hf_chlizer.fir() does not.
So I changed my OOT module's .xml to use ettus.rfnoc_fir_cci() instead of
hf_chlizer.fir() and output shows both I and Q samples are filtered
identically by real taps.
But ettus.rfnoc_fir_cci() does not seem to support complex_vector taps. So
I must revert to hf_chlizer.fir() in which case I get:
RuntimeError: RuntimeError: Invalid block definition in
/home/switchlanez/rfnoc/share/uhd/rfnoc/blocks/fir.xml: RuntimeError: Found
invalid arguments for block fir.
Or I could hack hf_chlizer.fir(). I started this by replacing int vectors
with std::complex vectors everywhere FIR taps were referenced in the
in-tree module's C++ library but I stopped when it traced up to block.h
because that may affect other modules.
-
What's the best approach to implement a vector of complex taps
reprogrammable during runtime?
-
My verilog code assumes one complex tap is 32 bits (leftmost 16 bits for
I, rightmost 16 bits for Q) and formats complex samples the same (in-tree
module also handles complex sample this way). Will UHD automatically
convert complex floats incoming from the host to sc16 for the embedded
settings registers?
Thanks,
Andrew
Hi,
I am developing a FIR filter that will eventually accepts complex taps
reprogrammable during runtime. As a first iteration, I want to verify it
works like the in-tree module with int_vector real taps. So I configure the
settings register in OOT module's .xml file to take int_vector taps but
running it returns:
RuntimeError: RuntimeError: not yet implemented: int_vector
I guess it's because the in-tree module's ettus.rfnoc_fir_cci() make
function supports int_vector whereas my rfnocmodtool generated make
function hf_chlizer.fir() does not.
So I changed my OOT module's .xml to use ettus.rfnoc_fir_cci() instead of
hf_chlizer.fir() and output shows both I and Q samples are filtered
identically by real taps.
But ettus.rfnoc_fir_cci() does not seem to support complex_vector taps. So
I must revert to hf_chlizer.fir() in which case I get:
RuntimeError: RuntimeError: Invalid block definition in
/home/switchlanez/rfnoc/share/uhd/rfnoc/blocks/fir.xml: RuntimeError: Found
invalid arguments for block fir.
Or I could hack hf_chlizer.fir(). I started this by replacing int vectors
with std::complex vectors everywhere FIR taps were referenced in the
in-tree module's C++ library but I stopped when it traced up to block.h
because that may affect other modules.
1) What's the best approach to implement a vector of complex taps
reprogrammable during runtime?
2) My verilog code assumes one complex tap is 32 bits (leftmost 16 bits for
I, rightmost 16 bits for Q) and formats complex samples the same (in-tree
module also handles complex sample this way). Will UHD automatically
convert complex floats incoming from the host to sc16 for the embedded
settings registers?
Thanks,
Andrew
AL
Andrew Lanez
Tue, Aug 8, 2017 10:00 AM
Typo, the 3rd to last paragraph should read:
Or I could hack rfnoc_fir_cci(). I started this by replacing int vectors
with std::complex vectors everywhere FIR taps were referenced in the
in-tree module's C++ library but I stopped when it traced up to block.h
because that may affect other modules.
On Tue, Aug 8, 2017 at 2:56 AM, Andrew Lanez switchlanez@gmail.com wrote:
Hi,
I am developing a FIR filter that will eventually accepts complex taps
reprogrammable during runtime. As a first iteration, I want to verify it
works like the in-tree module with int_vector real taps. So I configure the
settings register in OOT module's .xml file to take int_vector taps but
running it returns:
RuntimeError: RuntimeError: not yet implemented: int_vector
I guess it's because the in-tree module's ettus.rfnoc_fir_cci() make
function supports int_vector whereas my rfnocmodtool generated make
function hf_chlizer.fir() does not.
So I changed my OOT module's .xml to use ettus.rfnoc_fir_cci() instead of
hf_chlizer.fir() and output shows both I and Q samples are filtered
identically by real taps.
But ettus.rfnoc_fir_cci() does not seem to support complex_vector taps. So
I must revert to hf_chlizer.fir() in which case I get:
RuntimeError: RuntimeError: Invalid block definition in
/home/switchlanez/rfnoc/share/uhd/rfnoc/blocks/fir.xml: RuntimeError:
Found invalid arguments for block fir.
Or I could hack hf_chlizer.fir(). I started this by replacing int vectors
with std::complex vectors everywhere FIR taps were referenced in the
in-tree module's C++ library but I stopped when it traced up to block.h
because that may affect other modules.
-
What's the best approach to implement a vector of complex taps
reprogrammable during runtime?
-
My verilog code assumes one complex tap is 32 bits (leftmost 16 bits
for I, rightmost 16 bits for Q) and formats complex samples the same
(in-tree module also handles complex sample this way). Will UHD
automatically convert complex floats incoming from the host to sc16 for the
embedded settings registers?
Thanks,
Andrew
Typo, the 3rd to last paragraph should read:
Or I could hack *rfnoc_fir_cci()*. I started this by replacing int vectors
with std::complex vectors everywhere FIR taps were referenced in the
in-tree module's C++ library but I stopped when it traced up to block.h
because that may affect other modules.
On Tue, Aug 8, 2017 at 2:56 AM, Andrew Lanez <switchlanez@gmail.com> wrote:
> Hi,
>
> I am developing a FIR filter that will eventually accepts complex taps
> reprogrammable during runtime. As a first iteration, I want to verify it
> works like the in-tree module with int_vector real taps. So I configure the
> settings register in OOT module's .xml file to take int_vector taps but
> running it returns:
> RuntimeError: RuntimeError: not yet implemented: int_vector
>
> I guess it's because the in-tree module's ettus.rfnoc_fir_cci() make
> function supports int_vector whereas my rfnocmodtool generated make
> function hf_chlizer.fir() does not.
>
> So I changed my OOT module's .xml to use ettus.rfnoc_fir_cci() instead of
> hf_chlizer.fir() and output shows both I and Q samples are filtered
> identically by real taps.
>
> But ettus.rfnoc_fir_cci() does not seem to support complex_vector taps. So
> I must revert to hf_chlizer.fir() in which case I get:
> RuntimeError: RuntimeError: Invalid block definition in
> /home/switchlanez/rfnoc/share/uhd/rfnoc/blocks/fir.xml: RuntimeError:
> Found invalid arguments for block fir.
>
> Or I could hack hf_chlizer.fir(). I started this by replacing int vectors
> with std::complex vectors everywhere FIR taps were referenced in the
> in-tree module's C++ library but I stopped when it traced up to block.h
> because that may affect other modules.
>
> 1) What's the best approach to implement a vector of complex taps
> reprogrammable during runtime?
>
> 2) My verilog code assumes one complex tap is 32 bits (leftmost 16 bits
> for I, rightmost 16 bits for Q) and formats complex samples the same
> (in-tree module also handles complex sample this way). Will UHD
> automatically convert complex floats incoming from the host to sc16 for the
> embedded settings registers?
>
> Thanks,
> Andrew
>
EK
EJ Kreinar
Thu, Aug 10, 2017 3:51 PM
Hi Andrew,
The OOT module .xml file definition currently only supports writing scalar
registers, so you need a custom C++ driver. The int_vector option has not
been implemented, and honestly I'm not sure if it would even make sense
because there's many different ways the HDL could implement a "vector" of
taps... it's not really a one-size-fits-all problem.
My recommendation would be to model your hf_chlizer's C++ driver on the
in-tree fir_block_ctrl_impl. Use the sr_write functions to program your
taps as your HDL code requires.
You'll notice fir_block_ctrl_impl uses integer taps. This ends up being a
little clumsy when developing flowgraphs, since your flowgraph application
needs to handle the floating point / fixed point conversion. In the past,
I've created a C++ driver that accepts floating point inputs and converts
to fixed point before programming to FPGA registers. Your preference.
Hope this helps,
EJ
On Tue, Aug 8, 2017 at 6:00 AM, Andrew Lanez via USRP-users <
usrp-users@lists.ettus.com> wrote:
Typo, the 3rd to last paragraph should read:
Or I could hack rfnoc_fir_cci(). I started this by replacing int vectors
with std::complex vectors everywhere FIR taps were referenced in the
in-tree module's C++ library but I stopped when it traced up to block.h
because that may affect other modules.
On Tue, Aug 8, 2017 at 2:56 AM, Andrew Lanez switchlanez@gmail.com
wrote:
Hi,
I am developing a FIR filter that will eventually accepts complex taps
reprogrammable during runtime. As a first iteration, I want to verify it
works like the in-tree module with int_vector real taps. So I configure the
settings register in OOT module's .xml file to take int_vector taps but
running it returns:
RuntimeError: RuntimeError: not yet implemented: int_vector
I guess it's because the in-tree module's ettus.rfnoc_fir_cci() make
function supports int_vector whereas my rfnocmodtool generated make
function hf_chlizer.fir() does not.
So I changed my OOT module's .xml to use ettus.rfnoc_fir_cci() instead of
hf_chlizer.fir() and output shows both I and Q samples are filtered
identically by real taps.
But ettus.rfnoc_fir_cci() does not seem to support complex_vector taps.
So I must revert to hf_chlizer.fir() in which case I get:
RuntimeError: RuntimeError: Invalid block definition in
/home/switchlanez/rfnoc/share/uhd/rfnoc/blocks/fir.xml: RuntimeError:
Found invalid arguments for block fir.
Or I could hack hf_chlizer.fir(). I started this by replacing int vectors
with std::complex vectors everywhere FIR taps were referenced in the
in-tree module's C++ library but I stopped when it traced up to block.h
because that may affect other modules.
-
What's the best approach to implement a vector of complex taps
reprogrammable during runtime?
-
My verilog code assumes one complex tap is 32 bits (leftmost 16 bits
for I, rightmost 16 bits for Q) and formats complex samples the same
(in-tree module also handles complex sample this way). Will UHD
automatically convert complex floats incoming from the host to sc16 for the
embedded settings registers?
Thanks,
Andrew
Hi Andrew,
The OOT module .xml file definition currently only supports writing scalar
registers, so you need a custom C++ driver. The int_vector option has not
been implemented, and honestly I'm not sure if it would even make sense
because there's many different ways the HDL could implement a "vector" of
taps... it's not really a one-size-fits-all problem.
My recommendation would be to model your hf_chlizer's C++ driver on the
in-tree fir_block_ctrl_impl. Use the sr_write functions to program your
taps as your HDL code requires.
You'll notice fir_block_ctrl_impl uses integer taps. This ends up being a
little clumsy when developing flowgraphs, since your flowgraph application
needs to handle the floating point / fixed point conversion. In the past,
I've created a C++ driver that accepts floating point inputs and converts
to fixed point before programming to FPGA registers. Your preference.
Hope this helps,
EJ
On Tue, Aug 8, 2017 at 6:00 AM, Andrew Lanez via USRP-users <
usrp-users@lists.ettus.com> wrote:
> Typo, the 3rd to last paragraph should read:
>
> Or I could hack *rfnoc_fir_cci()*. I started this by replacing int vectors
> with std::complex vectors everywhere FIR taps were referenced in the
> in-tree module's C++ library but I stopped when it traced up to block.h
> because that may affect other modules.
>
> On Tue, Aug 8, 2017 at 2:56 AM, Andrew Lanez <switchlanez@gmail.com>
> wrote:
>
>> Hi,
>>
>> I am developing a FIR filter that will eventually accepts complex taps
>> reprogrammable during runtime. As a first iteration, I want to verify it
>> works like the in-tree module with int_vector real taps. So I configure the
>> settings register in OOT module's .xml file to take int_vector taps but
>> running it returns:
>> RuntimeError: RuntimeError: not yet implemented: int_vector
>>
>> I guess it's because the in-tree module's ettus.rfnoc_fir_cci() make
>> function supports int_vector whereas my rfnocmodtool generated make
>> function hf_chlizer.fir() does not.
>>
>> So I changed my OOT module's .xml to use ettus.rfnoc_fir_cci() instead of
>> hf_chlizer.fir() and output shows both I and Q samples are filtered
>> identically by real taps.
>>
>> But ettus.rfnoc_fir_cci() does not seem to support complex_vector taps.
>> So I must revert to hf_chlizer.fir() in which case I get:
>> RuntimeError: RuntimeError: Invalid block definition in
>> /home/switchlanez/rfnoc/share/uhd/rfnoc/blocks/fir.xml: RuntimeError:
>> Found invalid arguments for block fir.
>>
>> Or I could hack hf_chlizer.fir(). I started this by replacing int vectors
>> with std::complex vectors everywhere FIR taps were referenced in the
>> in-tree module's C++ library but I stopped when it traced up to block.h
>> because that may affect other modules.
>>
>> 1) What's the best approach to implement a vector of complex taps
>> reprogrammable during runtime?
>>
>> 2) My verilog code assumes one complex tap is 32 bits (leftmost 16 bits
>> for I, rightmost 16 bits for Q) and formats complex samples the same
>> (in-tree module also handles complex sample this way). Will UHD
>> automatically convert complex floats incoming from the host to sc16 for the
>> embedded settings registers?
>>
>> Thanks,
>> Andrew
>>
>
>
> _______________________________________________
> USRP-users mailing list
> USRP-users@lists.ettus.com
> http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com
>
>
AL
Andrew Lanez
Sun, Aug 13, 2017 11:30 AM
Hi Andrew,
The OOT module .xml file definition currently only supports writing scalar
registers, so you need a custom C++ driver. The int_vector option has not
been implemented, and honestly I'm not sure if it would even make sense
because there's many different ways the HDL could implement a "vector" of
taps... it's not really a one-size-fits-all problem.
My recommendation would be to model your hf_chlizer's C++ driver on the
in-tree fir_block_ctrl_impl. Use the sr_write functions to program your
taps as your HDL code requires.
You'll notice fir_block_ctrl_impl uses integer taps. This ends up being a
little clumsy when developing flowgraphs, since your flowgraph application
needs to handle the floating point / fixed point conversion. In the past,
I've created a C++ driver that accepts floating point inputs and converts
to fixed point before programming to FPGA registers. Your preference.
Hope this helps,
EJ
On Tue, Aug 8, 2017 at 6:00 AM, Andrew Lanez via USRP-users <
usrp-users@lists.ettus.com> wrote:
Typo, the 3rd to last paragraph should read:
Or I could hack rfnoc_fir_cci(). I started this by replacing int
vectors with std::complex vectors everywhere FIR taps were referenced in
the in-tree module's C++ library but I stopped when it traced up to block.h
because that may affect other modules.
On Tue, Aug 8, 2017 at 2:56 AM, Andrew Lanez switchlanez@gmail.com
wrote:
Hi,
I am developing a FIR filter that will eventually accepts complex taps
reprogrammable during runtime. As a first iteration, I want to verify it
works like the in-tree module with int_vector real taps. So I configure the
settings register in OOT module's .xml file to take int_vector taps but
running it returns:
RuntimeError: RuntimeError: not yet implemented: int_vector
I guess it's because the in-tree module's ettus.rfnoc_fir_cci() make
function supports int_vector whereas my rfnocmodtool generated make
function hf_chlizer.fir() does not.
So I changed my OOT module's .xml to use ettus.rfnoc_fir_cci() instead
of hf_chlizer.fir() and output shows both I and Q samples are filtered
identically by real taps.
But ettus.rfnoc_fir_cci() does not seem to support complex_vector taps.
So I must revert to hf_chlizer.fir() in which case I get:
RuntimeError: RuntimeError: Invalid block definition in
/home/switchlanez/rfnoc/share/uhd/rfnoc/blocks/fir.xml: RuntimeError:
Found invalid arguments for block fir.
Or I could hack hf_chlizer.fir(). I started this by replacing int
vectors with std::complex vectors everywhere FIR taps were referenced in
the in-tree module's C++ library but I stopped when it traced up to block.h
because that may affect other modules.
-
What's the best approach to implement a vector of complex taps
reprogrammable during runtime?
-
My verilog code assumes one complex tap is 32 bits (leftmost 16 bits
for I, rightmost 16 bits for Q) and formats complex samples the same
(in-tree module also handles complex sample this way). Will UHD
automatically convert complex floats incoming from the host to sc16 for the
embedded settings registers?
Thanks,
Andrew
EJ,
I spent some time wrestling with the 32-bit to 16-bit conversion in my
verilog noc block then realized doing the conversion in the C++ control
block driver might be more straightforward. I'm trying to digest the
following:
https://raw.githubusercontent.com/EttusResearch/fpga/b108e88865ee0fa68e685461681d8ca6a320b937/usrp3/lib/vita/float_to_iq.v
I can't tell if that converter is fixed-point. I'm inclined to believe it's
16-bit compressed floating point. Do you or anyone have references to do an
equivalent conversion in C++?
Andrew
On Thu, Aug 10, 2017 at 8:51 AM, EJ Kreinar <ejkreinar@gmail.com> wrote:
> Hi Andrew,
>
> The OOT module .xml file definition currently only supports writing scalar
> registers, so you need a custom C++ driver. The int_vector option has not
> been implemented, and honestly I'm not sure if it would even make sense
> because there's many different ways the HDL could implement a "vector" of
> taps... it's not really a one-size-fits-all problem.
>
> My recommendation would be to model your hf_chlizer's C++ driver on the
> in-tree fir_block_ctrl_impl. Use the sr_write functions to program your
> taps as your HDL code requires.
>
> You'll notice fir_block_ctrl_impl uses integer taps. This ends up being a
> little clumsy when developing flowgraphs, since your flowgraph application
> needs to handle the floating point / fixed point conversion. In the past,
> I've created a C++ driver that accepts floating point inputs and converts
> to fixed point before programming to FPGA registers. Your preference.
>
> Hope this helps,
> EJ
>
>
>
> On Tue, Aug 8, 2017 at 6:00 AM, Andrew Lanez via USRP-users <
> usrp-users@lists.ettus.com> wrote:
>
>> Typo, the 3rd to last paragraph should read:
>>
>> Or I could hack *rfnoc_fir_cci()*. I started this by replacing int
>> vectors with std::complex vectors everywhere FIR taps were referenced in
>> the in-tree module's C++ library but I stopped when it traced up to block.h
>> because that may affect other modules.
>>
>> On Tue, Aug 8, 2017 at 2:56 AM, Andrew Lanez <switchlanez@gmail.com>
>> wrote:
>>
>>> Hi,
>>>
>>> I am developing a FIR filter that will eventually accepts complex taps
>>> reprogrammable during runtime. As a first iteration, I want to verify it
>>> works like the in-tree module with int_vector real taps. So I configure the
>>> settings register in OOT module's .xml file to take int_vector taps but
>>> running it returns:
>>> RuntimeError: RuntimeError: not yet implemented: int_vector
>>>
>>> I guess it's because the in-tree module's ettus.rfnoc_fir_cci() make
>>> function supports int_vector whereas my rfnocmodtool generated make
>>> function hf_chlizer.fir() does not.
>>>
>>> So I changed my OOT module's .xml to use ettus.rfnoc_fir_cci() instead
>>> of hf_chlizer.fir() and output shows both I and Q samples are filtered
>>> identically by real taps.
>>>
>>> But ettus.rfnoc_fir_cci() does not seem to support complex_vector taps.
>>> So I must revert to hf_chlizer.fir() in which case I get:
>>> RuntimeError: RuntimeError: Invalid block definition in
>>> /home/switchlanez/rfnoc/share/uhd/rfnoc/blocks/fir.xml: RuntimeError:
>>> Found invalid arguments for block fir.
>>>
>>> Or I could hack hf_chlizer.fir(). I started this by replacing int
>>> vectors with std::complex vectors everywhere FIR taps were referenced in
>>> the in-tree module's C++ library but I stopped when it traced up to block.h
>>> because that may affect other modules.
>>>
>>> 1) What's the best approach to implement a vector of complex taps
>>> reprogrammable during runtime?
>>>
>>> 2) My verilog code assumes one complex tap is 32 bits (leftmost 16 bits
>>> for I, rightmost 16 bits for Q) and formats complex samples the same
>>> (in-tree module also handles complex sample this way). Will UHD
>>> automatically convert complex floats incoming from the host to sc16 for the
>>> embedded settings registers?
>>>
>>> Thanks,
>>> Andrew
>>>
>>
>>
>> _______________________________________________
>> USRP-users mailing list
>> USRP-users@lists.ettus.com
>> http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com
>>
>>
>
EK
EJ Kreinar
Mon, Aug 14, 2017 11:49 AM
Hi Andrew,
As far as I can tell, that particular verilog block implements a 32-bit
floating point to 16-bit fixed point conversion. The name may be a misnomer
because it does not actually break the input into I/Q channels.
For floating to fixed conversion in software, I usually refer to this
wikipedia page, which includes notation information and provides a
quick/easy conversion: https://en.wikipedia.org/wiki/Q_(number_format)
Usually my rule of thumb is that if there's a plausible way to do something
in software, it's better to do it in software :D The C++ control block
driver is a good place to wrap some helper code (e.g., converting taps,
calculating magic numbers, etc etc) around your time-critical and
performance-intensive FPGA operations.
EJ
On Sun, Aug 13, 2017 at 7:30 AM, Andrew Lanez switchlanez@gmail.com wrote:
EJ,
I spent some time wrestling with the 32-bit to 16-bit conversion in my
verilog noc block then realized doing the conversion in the C++ control
block driver might be more straightforward. I'm trying to digest the
following:
https://raw.githubusercontent.com/EttusResearch/fpga/b108e88
865ee0fa68e685461681d8ca6a320b937/usrp3/lib/vita/float_to_iq.v
I can't tell if that converter is fixed-point. I'm inclined to believe
it's 16-bit compressed floating point. Do you or anyone have references to
do an equivalent conversion in C++?
Andrew
On Thu, Aug 10, 2017 at 8:51 AM, EJ Kreinar ejkreinar@gmail.com wrote:
Hi Andrew,
The OOT module .xml file definition currently only supports writing
scalar registers, so you need a custom C++ driver. The int_vector option
has not been implemented, and honestly I'm not sure if it would even make
sense because there's many different ways the HDL could implement a
"vector" of taps... it's not really a one-size-fits-all problem.
My recommendation would be to model your hf_chlizer's C++ driver on the
in-tree fir_block_ctrl_impl. Use the sr_write functions to program your
taps as your HDL code requires.
You'll notice fir_block_ctrl_impl uses integer taps. This ends up being a
little clumsy when developing flowgraphs, since your flowgraph application
needs to handle the floating point / fixed point conversion. In the past,
I've created a C++ driver that accepts floating point inputs and converts
to fixed point before programming to FPGA registers. Your preference.
Hope this helps,
EJ
On Tue, Aug 8, 2017 at 6:00 AM, Andrew Lanez via USRP-users <
usrp-users@lists.ettus.com> wrote:
Typo, the 3rd to last paragraph should read:
Or I could hack rfnoc_fir_cci(). I started this by replacing int
vectors with std::complex vectors everywhere FIR taps were referenced in
the in-tree module's C++ library but I stopped when it traced up to block.h
because that may affect other modules.
On Tue, Aug 8, 2017 at 2:56 AM, Andrew Lanez switchlanez@gmail.com
wrote:
Hi,
I am developing a FIR filter that will eventually accepts complex taps
reprogrammable during runtime. As a first iteration, I want to verify it
works like the in-tree module with int_vector real taps. So I configure the
settings register in OOT module's .xml file to take int_vector taps but
running it returns:
RuntimeError: RuntimeError: not yet implemented: int_vector
I guess it's because the in-tree module's ettus.rfnoc_fir_cci() make
function supports int_vector whereas my rfnocmodtool generated make
function hf_chlizer.fir() does not.
So I changed my OOT module's .xml to use ettus.rfnoc_fir_cci() instead
of hf_chlizer.fir() and output shows both I and Q samples are filtered
identically by real taps.
But ettus.rfnoc_fir_cci() does not seem to support complex_vector taps.
So I must revert to hf_chlizer.fir() in which case I get:
RuntimeError: RuntimeError: Invalid block definition in
/home/switchlanez/rfnoc/share/uhd/rfnoc/blocks/fir.xml: RuntimeError:
Found invalid arguments for block fir.
Or I could hack hf_chlizer.fir(). I started this by replacing int
vectors with std::complex vectors everywhere FIR taps were referenced in
the in-tree module's C++ library but I stopped when it traced up to block.h
because that may affect other modules.
-
What's the best approach to implement a vector of complex taps
reprogrammable during runtime?
-
My verilog code assumes one complex tap is 32 bits (leftmost 16 bits
for I, rightmost 16 bits for Q) and formats complex samples the same
(in-tree module also handles complex sample this way). Will UHD
automatically convert complex floats incoming from the host to sc16 for the
embedded settings registers?
Thanks,
Andrew
Hi Andrew,
As far as I can tell, that particular verilog block implements a 32-bit
floating point to 16-bit fixed point conversion. The name may be a misnomer
because it does not actually break the input into I/Q channels.
For floating to fixed conversion in software, I usually refer to this
wikipedia page, which includes notation information and provides a
quick/easy conversion: https://en.wikipedia.org/wiki/Q_(number_format)
Usually my rule of thumb is that if there's a plausible way to do something
in software, it's better to do it in software :D The C++ control block
driver is a good place to wrap some helper code (e.g., converting taps,
calculating magic numbers, etc etc) around your time-critical and
performance-intensive FPGA operations.
EJ
On Sun, Aug 13, 2017 at 7:30 AM, Andrew Lanez <switchlanez@gmail.com> wrote:
> EJ,
>
> I spent some time wrestling with the 32-bit to 16-bit conversion in my
> verilog noc block then realized doing the conversion in the C++ control
> block driver might be more straightforward. I'm trying to digest the
> following:
>
> https://raw.githubusercontent.com/EttusResearch/fpga/b108e88
> 865ee0fa68e685461681d8ca6a320b937/usrp3/lib/vita/float_to_iq.v
>
> I can't tell if that converter is fixed-point. I'm inclined to believe
> it's 16-bit compressed floating point. Do you or anyone have references to
> do an equivalent conversion in C++?
>
> Andrew
>
> On Thu, Aug 10, 2017 at 8:51 AM, EJ Kreinar <ejkreinar@gmail.com> wrote:
>
>> Hi Andrew,
>>
>> The OOT module .xml file definition currently only supports writing
>> scalar registers, so you need a custom C++ driver. The int_vector option
>> has not been implemented, and honestly I'm not sure if it would even make
>> sense because there's many different ways the HDL could implement a
>> "vector" of taps... it's not really a one-size-fits-all problem.
>>
>> My recommendation would be to model your hf_chlizer's C++ driver on the
>> in-tree fir_block_ctrl_impl. Use the sr_write functions to program your
>> taps as your HDL code requires.
>>
>> You'll notice fir_block_ctrl_impl uses integer taps. This ends up being a
>> little clumsy when developing flowgraphs, since your flowgraph application
>> needs to handle the floating point / fixed point conversion. In the past,
>> I've created a C++ driver that accepts floating point inputs and converts
>> to fixed point before programming to FPGA registers. Your preference.
>>
>> Hope this helps,
>> EJ
>>
>>
>>
>> On Tue, Aug 8, 2017 at 6:00 AM, Andrew Lanez via USRP-users <
>> usrp-users@lists.ettus.com> wrote:
>>
>>> Typo, the 3rd to last paragraph should read:
>>>
>>> Or I could hack *rfnoc_fir_cci()*. I started this by replacing int
>>> vectors with std::complex vectors everywhere FIR taps were referenced in
>>> the in-tree module's C++ library but I stopped when it traced up to block.h
>>> because that may affect other modules.
>>>
>>> On Tue, Aug 8, 2017 at 2:56 AM, Andrew Lanez <switchlanez@gmail.com>
>>> wrote:
>>>
>>>> Hi,
>>>>
>>>> I am developing a FIR filter that will eventually accepts complex taps
>>>> reprogrammable during runtime. As a first iteration, I want to verify it
>>>> works like the in-tree module with int_vector real taps. So I configure the
>>>> settings register in OOT module's .xml file to take int_vector taps but
>>>> running it returns:
>>>> RuntimeError: RuntimeError: not yet implemented: int_vector
>>>>
>>>> I guess it's because the in-tree module's ettus.rfnoc_fir_cci() make
>>>> function supports int_vector whereas my rfnocmodtool generated make
>>>> function hf_chlizer.fir() does not.
>>>>
>>>> So I changed my OOT module's .xml to use ettus.rfnoc_fir_cci() instead
>>>> of hf_chlizer.fir() and output shows both I and Q samples are filtered
>>>> identically by real taps.
>>>>
>>>> But ettus.rfnoc_fir_cci() does not seem to support complex_vector taps.
>>>> So I must revert to hf_chlizer.fir() in which case I get:
>>>> RuntimeError: RuntimeError: Invalid block definition in
>>>> /home/switchlanez/rfnoc/share/uhd/rfnoc/blocks/fir.xml: RuntimeError:
>>>> Found invalid arguments for block fir.
>>>>
>>>> Or I could hack hf_chlizer.fir(). I started this by replacing int
>>>> vectors with std::complex vectors everywhere FIR taps were referenced in
>>>> the in-tree module's C++ library but I stopped when it traced up to block.h
>>>> because that may affect other modules.
>>>>
>>>> 1) What's the best approach to implement a vector of complex taps
>>>> reprogrammable during runtime?
>>>>
>>>> 2) My verilog code assumes one complex tap is 32 bits (leftmost 16 bits
>>>> for I, rightmost 16 bits for Q) and formats complex samples the same
>>>> (in-tree module also handles complex sample this way). Will UHD
>>>> automatically convert complex floats incoming from the host to sc16 for the
>>>> embedded settings registers?
>>>>
>>>> Thanks,
>>>> Andrew
>>>>
>>>
>>>
>>> _______________________________________________
>>> USRP-users mailing list
>>> USRP-users@lists.ettus.com
>>> http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com
>>>
>>>
>>
>
AL
Andrew Lanez
Mon, Aug 14, 2017 8:06 PM
Hi EJ,
Thanks for the pointers. Ok, I think I see now that float_to_iq module is
fixed point. Am I interpreting these lines of code correctly that put an
8-bit bound on the mantissa with a 2's complement sign bit, leaving the
remaining 8-bits for radix:
assign shift_val = (in[30:23] > 127)? (in[30:23] - 127): (127 - in[30:23]);
...
wire [15:0] final_val = (in[31] == 1)?(~shift + 1'b1):shift;
I've been pursuing this conversion from within my noc block but doing it in
the block controller instead is looking more attractive.
Thanks,
Andrew
On Mon, Aug 14, 2017 at 4:49 AM, EJ Kreinar ejkreinar@gmail.com wrote:
Hi Andrew,
As far as I can tell, that particular verilog block implements a 32-bit
floating point to 16-bit fixed point conversion. The name may be a misnomer
because it does not actually break the input into I/Q channels.
For floating to fixed conversion in software, I usually refer to this
wikipedia page, which includes notation information and provides a
quick/easy conversion: https://en.wikipedia.org/wiki/Q_(number_format)
Usually my rule of thumb is that if there's a plausible way to do
something in software, it's better to do it in software :D The C++ control
block driver is a good place to wrap some helper code (e.g., converting
taps, calculating magic numbers, etc etc) around your time-critical and
performance-intensive FPGA operations.
EJ
On Sun, Aug 13, 2017 at 7:30 AM, Andrew Lanez switchlanez@gmail.com
wrote:
EJ,
I spent some time wrestling with the 32-bit to 16-bit conversion in my
verilog noc block then realized doing the conversion in the C++ control
block driver might be more straightforward. I'm trying to digest the
following:
https://raw.githubusercontent.com/EttusResearch/fpga/b108e88
865ee0fa68e685461681d8ca6a320b937/usrp3/lib/vita/float_to_iq.v
I can't tell if that converter is fixed-point. I'm inclined to believe
it's 16-bit compressed floating point. Do you or anyone have references to
do an equivalent conversion in C++?
Andrew
On Thu, Aug 10, 2017 at 8:51 AM, EJ Kreinar ejkreinar@gmail.com wrote:
Hi Andrew,
The OOT module .xml file definition currently only supports writing
scalar registers, so you need a custom C++ driver. The int_vector option
has not been implemented, and honestly I'm not sure if it would even make
sense because there's many different ways the HDL could implement a
"vector" of taps... it's not really a one-size-fits-all problem.
My recommendation would be to model your hf_chlizer's C++ driver on the
in-tree fir_block_ctrl_impl. Use the sr_write functions to program your
taps as your HDL code requires.
You'll notice fir_block_ctrl_impl uses integer taps. This ends up being
a little clumsy when developing flowgraphs, since your flowgraph
application needs to handle the floating point / fixed point conversion. In
the past, I've created a C++ driver that accepts floating point inputs and
converts to fixed point before programming to FPGA registers. Your
preference.
Hope this helps,
EJ
On Tue, Aug 8, 2017 at 6:00 AM, Andrew Lanez via USRP-users <
usrp-users@lists.ettus.com> wrote:
Typo, the 3rd to last paragraph should read:
Or I could hack rfnoc_fir_cci(). I started this by replacing int
vectors with std::complex vectors everywhere FIR taps were referenced in
the in-tree module's C++ library but I stopped when it traced up to block.h
because that may affect other modules.
On Tue, Aug 8, 2017 at 2:56 AM, Andrew Lanez switchlanez@gmail.com
wrote:
Hi,
I am developing a FIR filter that will eventually accepts complex taps
reprogrammable during runtime. As a first iteration, I want to verify it
works like the in-tree module with int_vector real taps. So I configure the
settings register in OOT module's .xml file to take int_vector taps but
running it returns:
RuntimeError: RuntimeError: not yet implemented: int_vector
I guess it's because the in-tree module's ettus.rfnoc_fir_cci() make
function supports int_vector whereas my rfnocmodtool generated make
function hf_chlizer.fir() does not.
So I changed my OOT module's .xml to use ettus.rfnoc_fir_cci() instead
of hf_chlizer.fir() and output shows both I and Q samples are filtered
identically by real taps.
But ettus.rfnoc_fir_cci() does not seem to support complex_vector
taps. So I must revert to hf_chlizer.fir() in which case I get:
RuntimeError: RuntimeError: Invalid block definition in
/home/switchlanez/rfnoc/share/uhd/rfnoc/blocks/fir.xml: RuntimeError:
Found invalid arguments for block fir.
Or I could hack hf_chlizer.fir(). I started this by replacing int
vectors with std::complex vectors everywhere FIR taps were referenced in
the in-tree module's C++ library but I stopped when it traced up to block.h
because that may affect other modules.
-
What's the best approach to implement a vector of complex taps
reprogrammable during runtime?
-
My verilog code assumes one complex tap is 32 bits (leftmost 16
bits for I, rightmost 16 bits for Q) and formats complex samples the same
(in-tree module also handles complex sample this way). Will UHD
automatically convert complex floats incoming from the host to sc16 for the
embedded settings registers?
Thanks,
Andrew
Hi EJ,
Thanks for the pointers. Ok, I think I see now that float_to_iq module is
fixed point. Am I interpreting these lines of code correctly that put an
8-bit bound on the mantissa with a 2's complement sign bit, leaving the
remaining 8-bits for radix:
assign shift_val = (in[30:23] > 127)? (in[30:23] - 127): (127 - in[30:23]);
...
wire [15:0] final_val = (in[31] == 1)?(~shift + 1'b1):shift;
I've been pursuing this conversion from within my noc block but doing it in
the block controller instead is looking more attractive.
Thanks,
Andrew
On Mon, Aug 14, 2017 at 4:49 AM, EJ Kreinar <ejkreinar@gmail.com> wrote:
> Hi Andrew,
>
> As far as I can tell, that particular verilog block implements a 32-bit
> floating point to 16-bit fixed point conversion. The name may be a misnomer
> because it does not actually break the input into I/Q channels.
>
> For floating to fixed conversion in software, I usually refer to this
> wikipedia page, which includes notation information and provides a
> quick/easy conversion: https://en.wikipedia.org/wiki/Q_(number_format)
>
> Usually my rule of thumb is that if there's a plausible way to do
> something in software, it's better to do it in software :D The C++ control
> block driver is a good place to wrap some helper code (e.g., converting
> taps, calculating magic numbers, etc etc) around your time-critical and
> performance-intensive FPGA operations.
>
> EJ
>
> On Sun, Aug 13, 2017 at 7:30 AM, Andrew Lanez <switchlanez@gmail.com>
> wrote:
>
>> EJ,
>>
>> I spent some time wrestling with the 32-bit to 16-bit conversion in my
>> verilog noc block then realized doing the conversion in the C++ control
>> block driver might be more straightforward. I'm trying to digest the
>> following:
>>
>> https://raw.githubusercontent.com/EttusResearch/fpga/b108e88
>> 865ee0fa68e685461681d8ca6a320b937/usrp3/lib/vita/float_to_iq.v
>>
>> I can't tell if that converter is fixed-point. I'm inclined to believe
>> it's 16-bit compressed floating point. Do you or anyone have references to
>> do an equivalent conversion in C++?
>>
>> Andrew
>>
>> On Thu, Aug 10, 2017 at 8:51 AM, EJ Kreinar <ejkreinar@gmail.com> wrote:
>>
>>> Hi Andrew,
>>>
>>> The OOT module .xml file definition currently only supports writing
>>> scalar registers, so you need a custom C++ driver. The int_vector option
>>> has not been implemented, and honestly I'm not sure if it would even make
>>> sense because there's many different ways the HDL could implement a
>>> "vector" of taps... it's not really a one-size-fits-all problem.
>>>
>>> My recommendation would be to model your hf_chlizer's C++ driver on the
>>> in-tree fir_block_ctrl_impl. Use the sr_write functions to program your
>>> taps as your HDL code requires.
>>>
>>> You'll notice fir_block_ctrl_impl uses integer taps. This ends up being
>>> a little clumsy when developing flowgraphs, since your flowgraph
>>> application needs to handle the floating point / fixed point conversion. In
>>> the past, I've created a C++ driver that accepts floating point inputs and
>>> converts to fixed point before programming to FPGA registers. Your
>>> preference.
>>>
>>> Hope this helps,
>>> EJ
>>>
>>>
>>>
>>> On Tue, Aug 8, 2017 at 6:00 AM, Andrew Lanez via USRP-users <
>>> usrp-users@lists.ettus.com> wrote:
>>>
>>>> Typo, the 3rd to last paragraph should read:
>>>>
>>>> Or I could hack *rfnoc_fir_cci()*. I started this by replacing int
>>>> vectors with std::complex vectors everywhere FIR taps were referenced in
>>>> the in-tree module's C++ library but I stopped when it traced up to block.h
>>>> because that may affect other modules.
>>>>
>>>> On Tue, Aug 8, 2017 at 2:56 AM, Andrew Lanez <switchlanez@gmail.com>
>>>> wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> I am developing a FIR filter that will eventually accepts complex taps
>>>>> reprogrammable during runtime. As a first iteration, I want to verify it
>>>>> works like the in-tree module with int_vector real taps. So I configure the
>>>>> settings register in OOT module's .xml file to take int_vector taps but
>>>>> running it returns:
>>>>> RuntimeError: RuntimeError: not yet implemented: int_vector
>>>>>
>>>>> I guess it's because the in-tree module's ettus.rfnoc_fir_cci() make
>>>>> function supports int_vector whereas my rfnocmodtool generated make
>>>>> function hf_chlizer.fir() does not.
>>>>>
>>>>> So I changed my OOT module's .xml to use ettus.rfnoc_fir_cci() instead
>>>>> of hf_chlizer.fir() and output shows both I and Q samples are filtered
>>>>> identically by real taps.
>>>>>
>>>>> But ettus.rfnoc_fir_cci() does not seem to support complex_vector
>>>>> taps. So I must revert to hf_chlizer.fir() in which case I get:
>>>>> RuntimeError: RuntimeError: Invalid block definition in
>>>>> /home/switchlanez/rfnoc/share/uhd/rfnoc/blocks/fir.xml: RuntimeError:
>>>>> Found invalid arguments for block fir.
>>>>>
>>>>> Or I could hack hf_chlizer.fir(). I started this by replacing int
>>>>> vectors with std::complex vectors everywhere FIR taps were referenced in
>>>>> the in-tree module's C++ library but I stopped when it traced up to block.h
>>>>> because that may affect other modules.
>>>>>
>>>>> 1) What's the best approach to implement a vector of complex taps
>>>>> reprogrammable during runtime?
>>>>>
>>>>> 2) My verilog code assumes one complex tap is 32 bits (leftmost 16
>>>>> bits for I, rightmost 16 bits for Q) and formats complex samples the same
>>>>> (in-tree module also handles complex sample this way). Will UHD
>>>>> automatically convert complex floats incoming from the host to sc16 for the
>>>>> embedded settings registers?
>>>>>
>>>>> Thanks,
>>>>> Andrew
>>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> USRP-users mailing list
>>>> USRP-users@lists.ettus.com
>>>> http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com
>>>>
>>>>
>>>
>>
>
EK
EJ Kreinar
Tue, Aug 15, 2017 12:03 AM
Ehh, I dont think that's an accurate description of what's going on...
Take a look at the 32-bit floating point definition:
https://en.wikipedia.org/wiki/Single-precision_floating-point_format The
wikipedia definition seems to be essentially what's going on here, with the
added twist that the output is 16-bit fixed point, so there's some
shortcuts to get the datatypes to match.
Some quick thoughts... The sign bit specifies the sign of the value. The
8-bits pulled out into "shift_val" represents the exponent, while the
remaining 24-bits are the mantissa (captured in "shift" -- you can see the
"shift" variable takes the round_fraction and right-shifts by the
shift_val). I expect the magic numbers in round_fraction and shift are due
to the 16-bit fixed point output, and you'd want to confirm the Q-style
format (# integer bits, # fractional bits) is correct on the output.
You might be able to use this block to read convert a 32-bit floating point
register in the FPGA to your desired 16-bit fixed point, which could be a
fine solution. But if you're already programming taps, you definitely need
a C++ controller anyway, so I'd suggest doing the conversion there.
EJ
On Mon, Aug 14, 2017 at 4:06 PM, Andrew Lanez switchlanez@gmail.com wrote:
Hi EJ,
Thanks for the pointers. Ok, I think I see now that float_to_iq module is
fixed point. Am I interpreting these lines of code correctly that put an
8-bit bound on the mantissa with a 2's complement sign bit, leaving the
remaining 8-bits for radix:
assign shift_val = (in[30:23] > 127)? (in[30:23] - 127): (127 - in[30:23]);
...
wire [15:0] final_val = (in[31] == 1)?(~shift + 1'b1):shift;
I've been pursuing this conversion from within my noc block but doing it
in the block controller instead is looking more attractive.
Thanks,
Andrew
On Mon, Aug 14, 2017 at 4:49 AM, EJ Kreinar ejkreinar@gmail.com wrote:
Hi Andrew,
As far as I can tell, that particular verilog block implements a 32-bit
floating point to 16-bit fixed point conversion. The name may be a misnomer
because it does not actually break the input into I/Q channels.
For floating to fixed conversion in software, I usually refer to this
wikipedia page, which includes notation information and provides a
quick/easy conversion: https://en.wikipedia.org/wiki/Q_(number_format)
Usually my rule of thumb is that if there's a plausible way to do
something in software, it's better to do it in software :D The C++ control
block driver is a good place to wrap some helper code (e.g., converting
taps, calculating magic numbers, etc etc) around your time-critical and
performance-intensive FPGA operations.
EJ
On Sun, Aug 13, 2017 at 7:30 AM, Andrew Lanez switchlanez@gmail.com
wrote:
EJ,
I spent some time wrestling with the 32-bit to 16-bit conversion in my
verilog noc block then realized doing the conversion in the C++ control
block driver might be more straightforward. I'm trying to digest the
following:
https://raw.githubusercontent.com/EttusResearch/fpga/b108e88
865ee0fa68e685461681d8ca6a320b937/usrp3/lib/vita/float_to_iq.v
I can't tell if that converter is fixed-point. I'm inclined to believe
it's 16-bit compressed floating point. Do you or anyone have references to
do an equivalent conversion in C++?
Andrew
On Thu, Aug 10, 2017 at 8:51 AM, EJ Kreinar ejkreinar@gmail.com wrote:
Hi Andrew,
The OOT module .xml file definition currently only supports writing
scalar registers, so you need a custom C++ driver. The int_vector option
has not been implemented, and honestly I'm not sure if it would even make
sense because there's many different ways the HDL could implement a
"vector" of taps... it's not really a one-size-fits-all problem.
My recommendation would be to model your hf_chlizer's C++ driver on the
in-tree fir_block_ctrl_impl. Use the sr_write functions to program your
taps as your HDL code requires.
You'll notice fir_block_ctrl_impl uses integer taps. This ends up being
a little clumsy when developing flowgraphs, since your flowgraph
application needs to handle the floating point / fixed point conversion. In
the past, I've created a C++ driver that accepts floating point inputs and
converts to fixed point before programming to FPGA registers. Your
preference.
Hope this helps,
EJ
On Tue, Aug 8, 2017 at 6:00 AM, Andrew Lanez via USRP-users <
usrp-users@lists.ettus.com> wrote:
Typo, the 3rd to last paragraph should read:
Or I could hack rfnoc_fir_cci(). I started this by replacing int
vectors with std::complex vectors everywhere FIR taps were referenced in
the in-tree module's C++ library but I stopped when it traced up to block.h
because that may affect other modules.
On Tue, Aug 8, 2017 at 2:56 AM, Andrew Lanez switchlanez@gmail.com
wrote:
Hi,
I am developing a FIR filter that will eventually accepts complex
taps reprogrammable during runtime. As a first iteration, I want to verify
it works like the in-tree module with int_vector real taps. So I configure
the settings register in OOT module's .xml file to take int_vector taps but
running it returns:
RuntimeError: RuntimeError: not yet implemented: int_vector
I guess it's because the in-tree module's ettus.rfnoc_fir_cci() make
function supports int_vector whereas my rfnocmodtool generated make
function hf_chlizer.fir() does not.
So I changed my OOT module's .xml to use ettus.rfnoc_fir_cci()
instead of hf_chlizer.fir() and output shows both I and Q samples are
filtered identically by real taps.
But ettus.rfnoc_fir_cci() does not seem to support complex_vector
taps. So I must revert to hf_chlizer.fir() in which case I get:
RuntimeError: RuntimeError: Invalid block definition in
/home/switchlanez/rfnoc/share/uhd/rfnoc/blocks/fir.xml:
RuntimeError: Found invalid arguments for block fir.
Or I could hack hf_chlizer.fir(). I started this by replacing int
vectors with std::complex vectors everywhere FIR taps were referenced in
the in-tree module's C++ library but I stopped when it traced up to block.h
because that may affect other modules.
-
What's the best approach to implement a vector of complex taps
reprogrammable during runtime?
-
My verilog code assumes one complex tap is 32 bits (leftmost 16
bits for I, rightmost 16 bits for Q) and formats complex samples the same
(in-tree module also handles complex sample this way). Will UHD
automatically convert complex floats incoming from the host to sc16 for the
embedded settings registers?
Thanks,
Andrew
Ehh, I dont think that's an accurate description of what's going on...
Take a look at the 32-bit floating point definition:
https://en.wikipedia.org/wiki/Single-precision_floating-point_format The
wikipedia definition seems to be essentially what's going on here, with the
added twist that the output is 16-bit fixed point, so there's some
shortcuts to get the datatypes to match.
Some quick thoughts... The sign bit specifies the sign of the value. The
8-bits pulled out into "shift_val" represents the exponent, while the
remaining 24-bits are the mantissa (captured in "shift" -- you can see the
"shift" variable takes the round_fraction and right-shifts by the
shift_val). I expect the magic numbers in round_fraction and shift are due
to the 16-bit fixed point output, and you'd want to confirm the Q-style
format (# integer bits, # fractional bits) is correct on the output.
You might be able to use this block to read convert a 32-bit floating point
register in the FPGA to your desired 16-bit fixed point, which could be a
fine solution. But if you're already programming taps, you definitely need
a C++ controller anyway, so I'd suggest doing the conversion there.
EJ
On Mon, Aug 14, 2017 at 4:06 PM, Andrew Lanez <switchlanez@gmail.com> wrote:
> Hi EJ,
>
> Thanks for the pointers. Ok, I think I see now that float_to_iq module is
> fixed point. Am I interpreting these lines of code correctly that put an
> 8-bit bound on the mantissa with a 2's complement sign bit, leaving the
> remaining 8-bits for radix:
>
>
> assign shift_val = (in[30:23] > 127)? (in[30:23] - 127): (127 - in[30:23]);
>
> ...
>
> wire [15:0] final_val = (in[31] == 1)?(~shift + 1'b1):shift;
>
>
> I've been pursuing this conversion from within my noc block but doing it
> in the block controller instead is looking more attractive.
>
> Thanks,
> Andrew
>
>
>
>
> On Mon, Aug 14, 2017 at 4:49 AM, EJ Kreinar <ejkreinar@gmail.com> wrote:
>
>> Hi Andrew,
>>
>> As far as I can tell, that particular verilog block implements a 32-bit
>> floating point to 16-bit fixed point conversion. The name may be a misnomer
>> because it does not actually break the input into I/Q channels.
>>
>> For floating to fixed conversion in software, I usually refer to this
>> wikipedia page, which includes notation information and provides a
>> quick/easy conversion: https://en.wikipedia.org/wiki/Q_(number_format)
>>
>> Usually my rule of thumb is that if there's a plausible way to do
>> something in software, it's better to do it in software :D The C++ control
>> block driver is a good place to wrap some helper code (e.g., converting
>> taps, calculating magic numbers, etc etc) around your time-critical and
>> performance-intensive FPGA operations.
>>
>> EJ
>>
>> On Sun, Aug 13, 2017 at 7:30 AM, Andrew Lanez <switchlanez@gmail.com>
>> wrote:
>>
>>> EJ,
>>>
>>> I spent some time wrestling with the 32-bit to 16-bit conversion in my
>>> verilog noc block then realized doing the conversion in the C++ control
>>> block driver might be more straightforward. I'm trying to digest the
>>> following:
>>>
>>> https://raw.githubusercontent.com/EttusResearch/fpga/b108e88
>>> 865ee0fa68e685461681d8ca6a320b937/usrp3/lib/vita/float_to_iq.v
>>>
>>> I can't tell if that converter is fixed-point. I'm inclined to believe
>>> it's 16-bit compressed floating point. Do you or anyone have references to
>>> do an equivalent conversion in C++?
>>>
>>> Andrew
>>>
>>> On Thu, Aug 10, 2017 at 8:51 AM, EJ Kreinar <ejkreinar@gmail.com> wrote:
>>>
>>>> Hi Andrew,
>>>>
>>>> The OOT module .xml file definition currently only supports writing
>>>> scalar registers, so you need a custom C++ driver. The int_vector option
>>>> has not been implemented, and honestly I'm not sure if it would even make
>>>> sense because there's many different ways the HDL could implement a
>>>> "vector" of taps... it's not really a one-size-fits-all problem.
>>>>
>>>> My recommendation would be to model your hf_chlizer's C++ driver on the
>>>> in-tree fir_block_ctrl_impl. Use the sr_write functions to program your
>>>> taps as your HDL code requires.
>>>>
>>>> You'll notice fir_block_ctrl_impl uses integer taps. This ends up being
>>>> a little clumsy when developing flowgraphs, since your flowgraph
>>>> application needs to handle the floating point / fixed point conversion. In
>>>> the past, I've created a C++ driver that accepts floating point inputs and
>>>> converts to fixed point before programming to FPGA registers. Your
>>>> preference.
>>>>
>>>> Hope this helps,
>>>> EJ
>>>>
>>>>
>>>>
>>>> On Tue, Aug 8, 2017 at 6:00 AM, Andrew Lanez via USRP-users <
>>>> usrp-users@lists.ettus.com> wrote:
>>>>
>>>>> Typo, the 3rd to last paragraph should read:
>>>>>
>>>>> Or I could hack *rfnoc_fir_cci()*. I started this by replacing int
>>>>> vectors with std::complex vectors everywhere FIR taps were referenced in
>>>>> the in-tree module's C++ library but I stopped when it traced up to block.h
>>>>> because that may affect other modules.
>>>>>
>>>>> On Tue, Aug 8, 2017 at 2:56 AM, Andrew Lanez <switchlanez@gmail.com>
>>>>> wrote:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> I am developing a FIR filter that will eventually accepts complex
>>>>>> taps reprogrammable during runtime. As a first iteration, I want to verify
>>>>>> it works like the in-tree module with int_vector real taps. So I configure
>>>>>> the settings register in OOT module's .xml file to take int_vector taps but
>>>>>> running it returns:
>>>>>> RuntimeError: RuntimeError: not yet implemented: int_vector
>>>>>>
>>>>>> I guess it's because the in-tree module's ettus.rfnoc_fir_cci() make
>>>>>> function supports int_vector whereas my rfnocmodtool generated make
>>>>>> function hf_chlizer.fir() does not.
>>>>>>
>>>>>> So I changed my OOT module's .xml to use ettus.rfnoc_fir_cci()
>>>>>> instead of hf_chlizer.fir() and output shows both I and Q samples are
>>>>>> filtered identically by real taps.
>>>>>>
>>>>>> But ettus.rfnoc_fir_cci() does not seem to support complex_vector
>>>>>> taps. So I must revert to hf_chlizer.fir() in which case I get:
>>>>>> RuntimeError: RuntimeError: Invalid block definition in
>>>>>> /home/switchlanez/rfnoc/share/uhd/rfnoc/blocks/fir.xml:
>>>>>> RuntimeError: Found invalid arguments for block fir.
>>>>>>
>>>>>> Or I could hack hf_chlizer.fir(). I started this by replacing int
>>>>>> vectors with std::complex vectors everywhere FIR taps were referenced in
>>>>>> the in-tree module's C++ library but I stopped when it traced up to block.h
>>>>>> because that may affect other modules.
>>>>>>
>>>>>> 1) What's the best approach to implement a vector of complex taps
>>>>>> reprogrammable during runtime?
>>>>>>
>>>>>> 2) My verilog code assumes one complex tap is 32 bits (leftmost 16
>>>>>> bits for I, rightmost 16 bits for Q) and formats complex samples the same
>>>>>> (in-tree module also handles complex sample this way). Will UHD
>>>>>> automatically convert complex floats incoming from the host to sc16 for the
>>>>>> embedded settings registers?
>>>>>>
>>>>>> Thanks,
>>>>>> Andrew
>>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> USRP-users mailing list
>>>>> USRP-users@lists.ettus.com
>>>>> http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com
>>>>>
>>>>>
>>>>
>>>
>>
>