Re: [USRP-users] RFNoC: complex_vector support from reprogrammable embedded settings registers
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 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 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 >> 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 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 > wrote: >
Re: [USRP-users] RFNoC: complex_vector support from reprogrammable embedded settings registers
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 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 > 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 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 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
Re: [USRP-users] RFNoC: complex_vector support from reprogrammable embedded settings registers
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 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 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 >>> 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_l
Re: [USRP-users] RFNoC: complex_vector support from reprogrammable embedded settings registers
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 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 >> 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 >> >> > ___ USRP-users mailing list USRP-users@lists.ettus.com http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com
Re: [USRP-users] RFNoC: complex_vector support from reprogrammable embedded settings registers
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 > 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 > > ___ USRP-users mailing list USRP-users@lists.ettus.com http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com
Re: [USRP-users] RFNoC: complex_vector support from reprogrammable embedded settings registers
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 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