Re: [USRP-users] RFNoC: FIR Filter final tap never gets written to settings register
Hey there, A pretty useful test to see what's going on in hardware domain would be like this: File source => FIR => FIFO => File sink In your file source, I'd suggest making a file that's all complex zeros except for one sample that is set to "1" (or 1+1j). Running an impulse (Dirac Delta) through a FIR filter will output each FIR tap, one at a time. Just look at the output of the file sink and confirm all the taps have been programmed correctly! Hope this helps, EJ On Sat, Apr 21, 2018, 3:57 AM switchlanez via USRP-users < usrp-users@lists.ettus.com> wrote: > Oh yeah... I actually knew that! Noticed that line several months ago but > overlooked it this time because I was so determined to find the culprit for > something else (Function Probe polling a file of tap values to rewrite taps > to noc FIR block causes splashing across spectrum). Might post a new topic > on that with video if we can't figure it out. > > That half sample shift doesn't happen when we run noc_block_fir_filter > against its SystemVerilog testbench. Hoping the shift only happens if > datastream crosses from hardware to host domain which would be fine since > our application keeps the datastream on hardware. Just not sure how to > verify no half sample shift is happening in the hardware domain. > > On Fri, Apr 20, 2018 at 3:56 PM, Jon Pendlum via USRP-users < > usrp-users@lists.ettus.com> wrote: > >> Hey Andrew, >> >> The next line in fir_block_ctrl_impl.cpp sends the final tap: >> sr_write(SR_RELOAD_TLAST, uint32_t(taps.back())); >> >> The half a sample shift is odd though. >> >> On Sat, Apr 21, 2018, 6:23 AM Marcus D. Leech via USRP-users < >> usrp-users@lists.ettus.com> wrote: >> >>> On 04/20/2018 12:01 PM, switchlanez via USRP-users wrote: >>> >>> Hello, >>> >>> >>> >>> An oddity regarding the RFNoC FIR Filter block. fir_block_ctrl_impl.cpp >>> writes tap values to the settings registers with: >>> >>> >>> >>> for (size_t i = 0; i < taps.size() - 1; i++) { >>> sr_write(SR_RELOAD, uint32_t(taps[i])); >>> >>> } >>> >>> >>> >>> which loops from 0 to taps.size() - 1. So if I define 41 taps from GRC, >>> it only takes taps indexed from 0 to 39 and never writes tap index 40 (the >>> 41st tap) to the settings register. >>> >>> >>> >>> I sort of confirmed this by comparing the RFNoC FIR Filter output >>> against the GNU Radio Decimating FIR Filter (with Decimation=1) output with >>> the same 41 taps and same input fed to both. Output gets shifted by half >>> of a complex sample: >>> >>> >>> >>> GR FIR: >>> >>> 1 + .997j >>> >>> .994 + .991j >>> >>> .988 + ... >>> >>> >>> >>> RFNoC FIR: >>> >>> 0 + 1j >>> >>> .997 +.994j >>> >>> .991 + .988j >>> >>> >>> >>> Which is an effect of a FIR filter that has an even number of taps (40 >>> instead of 41). >>> >>> >>> >>> So I modified the condition in the FIR driver file to write from 0 >>> to taps.size() instead of taps.size()-1. Defined the 1st tap value to >>> be 1000 with all remaining 40 taps as 0s. Viewed output on a spec an and >>> saw nothing on output. Then moved the non-zero tap to the middle (21st >>> index) with leading 20 and trailing 20 taps being 0s and saw the input fed >>> to output. Now if I didn't modify the FIR driver file so it stops at >>> taps.size()-1 and writes only 40 of my 41 taps and set the first tap to >>> 1000 with 40 trailing zeros, I see input fed to output. Was the >>> taps.size()-1 check intentional? >>> >>> >>> >>> Andrew >>> >>> This definitely looks to me like a subtle bug in the "off by one" error >>> category. >>> >>> One of our RFNoC devs will probably chime in at this point, and provide >>> an opinion >>> >>> >>> >>> ___ >>> 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 >> >> > ___ > 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: FIR Filter final tap never gets written to settings register
Oh yeah... I actually knew that! Noticed that line several months ago but overlooked it this time because I was so determined to find the culprit for something else (Function Probe polling a file of tap values to rewrite taps to noc FIR block causes splashing across spectrum). Might post a new topic on that with video if we can't figure it out. That half sample shift doesn't happen when we run noc_block_fir_filter against its SystemVerilog testbench. Hoping the shift only happens if datastream crosses from hardware to host domain which would be fine since our application keeps the datastream on hardware. Just not sure how to verify no half sample shift is happening in the hardware domain. On Fri, Apr 20, 2018 at 3:56 PM, Jon Pendlum via USRP-users < usrp-users@lists.ettus.com> wrote: > Hey Andrew, > > The next line in fir_block_ctrl_impl.cpp sends the final tap: > sr_write(SR_RELOAD_TLAST, uint32_t(taps.back())); > > The half a sample shift is odd though. > > On Sat, Apr 21, 2018, 6:23 AM Marcus D. Leech via USRP-users < > usrp-users@lists.ettus.com> wrote: > >> On 04/20/2018 12:01 PM, switchlanez via USRP-users wrote: >> >> Hello, >> >> >> >> An oddity regarding the RFNoC FIR Filter block. fir_block_ctrl_impl.cpp >> writes tap values to the settings registers with: >> >> >> >> for (size_t i = 0; i < taps.size() - 1; i++) { >> sr_write(SR_RELOAD, uint32_t(taps[i])); >> >> } >> >> >> >> which loops from 0 to taps.size() - 1. So if I define 41 taps from GRC, >> it only takes taps indexed from 0 to 39 and never writes tap index 40 (the >> 41st tap) to the settings register. >> >> >> >> I sort of confirmed this by comparing the RFNoC FIR Filter output >> against the GNU Radio Decimating FIR Filter (with Decimation=1) output with >> the same 41 taps and same input fed to both. Output gets shifted by half >> of a complex sample: >> >> >> >> GR FIR: >> >> 1 + .997j >> >> .994 + .991j >> >> .988 + ... >> >> >> >> RFNoC FIR: >> >> 0 + 1j >> >> .997 +.994j >> >> .991 + .988j >> >> >> >> Which is an effect of a FIR filter that has an even number of taps (40 >> instead of 41). >> >> >> >> So I modified the condition in the FIR driver file to write from 0 >> to taps.size() instead of taps.size()-1. Defined the 1st tap value to >> be 1000 with all remaining 40 taps as 0s. Viewed output on a spec an and >> saw nothing on output. Then moved the non-zero tap to the middle (21st >> index) with leading 20 and trailing 20 taps being 0s and saw the input fed >> to output. Now if I didn't modify the FIR driver file so it stops at >> taps.size()-1 and writes only 40 of my 41 taps and set the first tap to >> 1000 with 40 trailing zeros, I see input fed to output. Was the >> taps.size()-1 check intentional? >> >> >> >> Andrew >> >> This definitely looks to me like a subtle bug in the "off by one" error >> category. >> >> One of our RFNoC devs will probably chime in at this point, and provide >> an opinion >> >> >> >> ___ >> 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 > > ___ USRP-users mailing list USRP-users@lists.ettus.com http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com
Re: [USRP-users] RFNoC: FIR Filter final tap never gets written to settings register
Hey Andrew, The next line in fir_block_ctrl_impl.cpp sends the final tap: sr_write(SR_RELOAD_TLAST, uint32_t(taps.back())); The half a sample shift is odd though. On Sat, Apr 21, 2018, 6:23 AM Marcus D. Leech via USRP-users < usrp-users@lists.ettus.com> wrote: > On 04/20/2018 12:01 PM, switchlanez via USRP-users wrote: > > Hello, > > > > An oddity regarding the RFNoC FIR Filter block. fir_block_ctrl_impl.cpp > writes tap values to the settings registers with: > > > > for (size_t i = 0; i < taps.size() - 1; i++) { > sr_write(SR_RELOAD, uint32_t(taps[i])); > > } > > > > which loops from 0 to taps.size() - 1. So if I define 41 taps from GRC, it > only takes taps indexed from 0 to 39 and never writes tap index 40 (the > 41st tap) to the settings register. > > > > I sort of confirmed this by comparing the RFNoC FIR Filter output > against the GNU Radio Decimating FIR Filter (with Decimation=1) output with > the same 41 taps and same input fed to both. Output gets shifted by half > of a complex sample: > > > > GR FIR: > > 1 + .997j > > .994 + .991j > > .988 + ... > > > > RFNoC FIR: > > 0 + 1j > > .997 +.994j > > .991 + .988j > > > > Which is an effect of a FIR filter that has an even number of taps (40 > instead of 41). > > > > So I modified the condition in the FIR driver file to write from 0 > to taps.size() instead of taps.size()-1. Defined the 1st tap value to > be 1000 with all remaining 40 taps as 0s. Viewed output on a spec an and > saw nothing on output. Then moved the non-zero tap to the middle (21st > index) with leading 20 and trailing 20 taps being 0s and saw the input fed > to output. Now if I didn't modify the FIR driver file so it stops at > taps.size()-1 and writes only 40 of my 41 taps and set the first tap to > 1000 with 40 trailing zeros, I see input fed to output. Was the > taps.size()-1 check intentional? > > > > Andrew > > This definitely looks to me like a subtle bug in the "off by one" error > category. > > One of our RFNoC devs will probably chime in at this point, and provide an > opinion > > > > ___ > 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: FIR Filter final tap never gets written to settings register
On 04/20/2018 12:01 PM, switchlanez via USRP-users wrote: Hello, An oddity regarding the RFNoC FIR Filter block. fir_block_ctrl_impl.cpp writes tap values to the settings registers with: for (size_t i = 0; i < taps.size() - 1; i++) { sr_write(SR_RELOAD, uint32_t(taps[i])); } which loops from 0 to taps.size() - 1. So if I define 41 taps from GRC, it only takes taps indexed from 0 to 39 and never writes tap index 40 (the 41st tap) to the settings register. I sort of confirmed this by comparing the RFNoC FIR Filter output against the GNU Radio Decimating FIR Filter (with Decimation=1) output with the same 41 taps and same input fed to both. Output gets shifted by half of a complex sample: GR FIR: 1 + .997j .994 + .991j .988 + ... RFNoC FIR: 0 + 1j .997 +.994j .991 + .988j Which is an effect of a FIR filter that has an even number of taps (40 instead of 41). So I modified the condition in the FIR driver file to write from 0 to taps.size() instead of taps.size()-1. Defined the 1st tap value to be 1000 with all remaining 40 taps as 0s. Viewed output on a spec an and saw nothing on output. Then moved the non-zero tap to the middle (21st index) with leading 20 and trailing 20 taps being 0s and saw the input fed to output. Now if I didn't modify the FIR driver file so it stops at taps.size()-1 and writes only 40 of my 41 taps and set the first tap to 1000 with 40 trailing zeros, I see input fed to output. Was the taps.size()-1 check intentional? Andrew This definitely looks to me like a subtle bug in the "off by one" error category. One of our RFNoC devs will probably chime in at this point, and provide an opinion ___ USRP-users mailing list USRP-users@lists.ettus.com http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com
[USRP-users] RFNoC: FIR Filter final tap never gets written to settings register
Hello, An oddity regarding the RFNoC FIR Filter block. fir_block_ctrl_impl.cpp writes tap values to the settings registers with: for (size_t i = 0; i < taps.size() - 1; i++) { sr_write(SR_RELOAD, uint32_t(taps[i])); } which loops from 0 to taps.size() - 1. So if I define 41 taps from GRC, it only takes taps indexed from 0 to 39 and never writes tap index 40 (the 41st tap) to the settings register. I sort of confirmed this by comparing the RFNoC FIR Filter output against the GNU Radio Decimating FIR Filter (with Decimation=1) output with the same 41 taps and same input fed to both. Output gets shifted by half of a complex sample: GR FIR: 1 + .997j .994 + .991j .988 + ... RFNoC FIR: 0 + 1j .997 +.994j .991 + .988j Which is an effect of a FIR filter that has an even number of taps (40 instead of 41). So I modified the condition in the FIR driver file to write from 0 to taps.size() instead of taps.size()-1. Defined the 1st tap value to be 1000 with all remaining 40 taps as 0s. Viewed output on a spec an and saw nothing on output. Then moved the non-zero tap to the middle (21st index) with leading 20 and trailing 20 taps being 0s and saw the input fed to output. Now if I didn't modify the FIR driver file so it stops at taps.size()-1 and writes only 40 of my 41 taps and set the first tap to 1000 with 40 trailing zeros, I see input fed to output. Was the taps.size()-1 check intentional? Andrew ___ USRP-users mailing list USRP-users@lists.ettus.com http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com