usrp-users@lists.ettus.com

Discussion and technical support related to USRP, UHD, RFNoC

View all threads

Some questions regarding DDC implementation

FR
Francesco Restuccia
Fri, Oct 11, 2019 5:56 PM

Dear all,
I have some questions regarding the DDC implementation (ddc_chain.v, usrp2):

  1. Why do we need two half-band filters (one large and one small) after the CIC? What is their purpose? Can’t we use just one half-band?
  2. What is the purpose of the scale factor multiplication after hb2? What does it compensate for? How do we decide its value?

Thanks,
Francesco

Dear all, I have some questions regarding the DDC implementation (ddc_chain.v, usrp2): 1) Why do we need two half-band filters (one large and one small) after the CIC? What is their purpose? Can’t we use just one half-band? 2) What is the purpose of the scale factor multiplication after hb2? What does it compensate for? How do we decide its value? Thanks, Francesco
MB
Martin Braun
Fri, Oct 11, 2019 11:08 PM

Half-Bands are very flat in the passband, and somewhat efficient to
implement because every second tap is zero. The CIC on the other hand, is
super efficient, but has a horrible frequency response.

So, you want to use the half-bands for decimation whenever possible. You
will have fewer aliases, the spectrum looks nicer, etc.

More halfbands is always better. But two halfbands was chosen because on
the N210, it's a good compromise between available resources and spectral
improvements. Also, keep in mind that you can only stack halfbands as long
as your decimation is a multiple of two. If your decimation is 6 (= 2 * 3),
then you can only use one halfband, and set the CIC to 3. In other words,
adding another halfband only enables rates where the decimation rate is a
multiple of 8, and so on.

Next, why are they different. That was another compromise. More taps are
always better, so why not use the bigger one twice? That's because when
cascading the halfbands, the fidelity of the second filter reduces the
requirement for a super-good first filter. If you draw this on a piece of
paper, it's more obvious, but here's an attempt at writing it as text:
Fewer taps in a halfband mean the transition band (from passband to stop
band) is wider, which makes the flat passband smaller. However, because the
second half-band will further reduce the total available bandwidth, you
don't need a super sharp transition zone.

Finally, what does the multiplier do. In software, we calculate a total
gain of our DSP chain, based on the CIC settings and some other numbers we
have figured out. For example, the CORDIC has an almost constant, non-zero
gain. and the CIC decimator has a non-constant gain which is a function of
the decimation (all of this because we're doing fixpoint math). We try and
negate this as much as possible by multiplying the output with a
compensation factor.

-- M

On Fri, Oct 11, 2019 at 10:57 AM Francesco Restuccia via USRP-users <
usrp-users@lists.ettus.com> wrote:

Dear all,
I have some questions regarding the DDC implementation (ddc_chain.v,
usrp2):

  1. Why do we need two half-band filters (one large and one small) after
    the CIC? What is their purpose? Can’t we use just one half-band?
  2. What is the purpose of the scale factor multiplication after hb2? What
    does it compensate for? How do we decide its value?

Thanks,
Francesco


USRP-users mailing list
USRP-users@lists.ettus.com
http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com

Half-Bands are very flat in the passband, and somewhat efficient to implement because every second tap is zero. The CIC on the other hand, is super efficient, but has a horrible frequency response. So, you want to use the half-bands for decimation whenever possible. You will have fewer aliases, the spectrum looks nicer, etc. More halfbands is always better. But two halfbands was chosen because on the N210, it's a good compromise between available resources and spectral improvements. Also, keep in mind that you can only stack halfbands as long as your decimation is a multiple of two. If your decimation is 6 (= 2 * 3), then you can only use one halfband, and set the CIC to 3. In other words, adding another halfband only enables rates where the decimation rate is a multiple of 8, and so on. Next, why are they different. That was another compromise. More taps are always better, so why not use the bigger one twice? That's because when cascading the halfbands, the fidelity of the second filter reduces the requirement for a super-good first filter. If you draw this on a piece of paper, it's more obvious, but here's an attempt at writing it as text: Fewer taps in a halfband mean the transition band (from passband to stop band) is wider, which makes the flat passband smaller. However, because the second half-band will further reduce the total available bandwidth, you don't need a super sharp transition zone. Finally, what does the multiplier do. In software, we calculate a total gain of our DSP chain, based on the CIC settings and some other numbers we have figured out. For example, the CORDIC has an almost constant, non-zero gain. and the CIC decimator has a non-constant gain which is a function of the decimation (all of this because we're doing fixpoint math). We try and negate this as much as possible by multiplying the output with a compensation factor. -- M On Fri, Oct 11, 2019 at 10:57 AM Francesco Restuccia via USRP-users < usrp-users@lists.ettus.com> wrote: > Dear all, > I have some questions regarding the DDC implementation (ddc_chain.v, > usrp2): > > 1) Why do we need two half-band filters (one large and one small) after > the CIC? What is their purpose? Can’t we use just one half-band? > 2) What is the purpose of the scale factor multiplication after hb2? What > does it compensate for? How do we decide its value? > > Thanks, > Francesco > _______________________________________________ > USRP-users mailing list > USRP-users@lists.ettus.com > http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com >
FR
Francesco Restuccia
Sat, Oct 12, 2019 1:54 PM

Hi Martin,

Thanks for your response --
Could you further clarify the following pieces of code in
rx_dsp_core_200.cpp regarding the scaling factor?

const double rate_pow = std::pow(double(decim & 0xff), 4);
_scaling_adjustment = std::pow(2, ceil_log2(rate_pow))/(1.65*rate_pow);
this->update_scalar();

where update_scalar is:

void update_scalar(void){
        const double factor = 1.0 +
std::max(ceil_log2(_scaling_adjustment), 0.0);
        const double target_scalar = (1 <<
17)_scaling_adjustment/_dsp_extra_scaling/factor;
        const int32_t actual_scalar = boost::math::iround(target_scalar);
        _fxpt_scalar_correction = target_scalar/actual_scalar
factor;
//should be small
        _iface->poke32(REG_DSP_RX_SCALE_IQ, actual_scalar);
    }

Would be nice to understand the rationale behind these constants and
calculations.

Thanks,
Francesco

On 10/11/19 7:08 PM, Martin Braun wrote:

Half-Bands are very flat in the passband, and somewhat efficient to
implement because every second tap is zero. The CIC on the other hand,
is super efficient, but has a horrible frequency response.

So, you want to use the half-bands for decimation whenever possible.
You will have fewer aliases, the spectrum looks nicer, etc.

More halfbands is always better. But two halfbands was chosen because
on the N210, it's a good compromise between available resources and
spectral improvements. Also, keep in mind that you can only stack
halfbands as long as your decimation is a multiple of two. If your
decimation is 6 (= 2 * 3), then you can only use one halfband, and set
the CIC to 3. In other words, adding another halfband only enables
rates where the decimation rate is a multiple of 8, and so on.

Next, why are they different. That was another compromise. More taps
are always better, so why not use the bigger one twice? That's because
when cascading the halfbands, the fidelity of the second filter
reduces the requirement for a super-good first filter. If you draw
this on a piece of paper, it's more obvious, but here's an attempt at
writing it as text: Fewer taps in a halfband mean the transition band
(from passband to stop band) is wider, which makes the flat passband
smaller. However, because the second half-band will further reduce the
total available bandwidth, you don't need a super sharp transition zone.

Finally, what does the multiplier do. In software, we calculate a
total gain of our DSP chain, based on the CIC settings and some other
numbers we have figured out. For example, the CORDIC has an almost
constant, non-zero gain. and the CIC decimator has a non-constant gain
which is a function of the decimation (all of this because we're doing
fixpoint math). We try and negate this as much as possible by
multiplying the output with a compensation factor.

-- M

On Fri, Oct 11, 2019 at 10:57 AM Francesco Restuccia via USRP-users
<usrp-users@lists.ettus.com mailto:usrp-users@lists.ettus.com> wrote:

 Dear all,
 I have some questions regarding the DDC implementation
 (ddc_chain.v, usrp2):

 1) Why do we need two half-band filters (one large and one small)
 after the CIC? What is their purpose? Can’t we use just one
 half-band?
 2) What is the purpose of the scale factor multiplication after
 hb2? What does it compensate for? How do we decide its value?

 Thanks,
 Francesco
 _______________________________________________
 USRP-users mailing list
 USRP-users@lists.ettus.com <mailto:USRP-users@lists.ettus.com>
 http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com
Hi Martin, Thanks for your response -- Could you further clarify the following pieces of code in rx_dsp_core_200.cpp regarding the scaling factor? const double rate_pow = std::pow(double(decim & 0xff), 4); _scaling_adjustment = std::pow(2, ceil_log2(rate_pow))/(1.65*rate_pow); this->update_scalar(); where update_scalar is: void update_scalar(void){         const double factor = 1.0 + std::max(ceil_log2(_scaling_adjustment), 0.0);         const double target_scalar = (1 << 17)*_scaling_adjustment/_dsp_extra_scaling/factor;         const int32_t actual_scalar = boost::math::iround(target_scalar);         _fxpt_scalar_correction = target_scalar/actual_scalar*factor; //should be small         _iface->poke32(REG_DSP_RX_SCALE_IQ, actual_scalar);     } Would be nice to understand the rationale behind these constants and calculations. Thanks, Francesco On 10/11/19 7:08 PM, Martin Braun wrote: > Half-Bands are very flat in the passband, and somewhat efficient to > implement because every second tap is zero. The CIC on the other hand, > is super efficient, but has a horrible frequency response. > > So, you want to use the half-bands for decimation whenever possible. > You will have fewer aliases, the spectrum looks nicer, etc. > > More halfbands is always better. But two halfbands was chosen because > on the N210, it's a good compromise between available resources and > spectral improvements. Also, keep in mind that you can only stack > halfbands as long as your decimation is a multiple of two. If your > decimation is 6 (= 2 * 3), then you can only use one halfband, and set > the CIC to 3. In other words, adding another halfband only enables > rates where the decimation rate is a multiple of 8, and so on. > > Next, why are they different. That was another compromise. More taps > are always better, so why not use the bigger one twice? That's because > when cascading the halfbands, the fidelity of the second filter > reduces the requirement for a super-good first filter. If you draw > this on a piece of paper, it's more obvious, but here's an attempt at > writing it as text: Fewer taps in a halfband mean the transition band > (from passband to stop band) is wider, which makes the flat passband > smaller. However, because the second half-band will further reduce the > total available bandwidth, you don't need a super sharp transition zone. > > Finally, what does the multiplier do. In software, we calculate a > total gain of our DSP chain, based on the CIC settings and some other > numbers we have figured out. For example, the CORDIC has an almost > constant, non-zero gain. and the CIC decimator has a non-constant gain > which is a function of the decimation (all of this because we're doing > fixpoint math). We try and negate this as much as possible by > multiplying the output with a compensation factor. > > -- M > > On Fri, Oct 11, 2019 at 10:57 AM Francesco Restuccia via USRP-users > <usrp-users@lists.ettus.com <mailto:usrp-users@lists.ettus.com>> wrote: > > Dear all, > I have some questions regarding the DDC implementation > (ddc_chain.v, usrp2): > > 1) Why do we need two half-band filters (one large and one small) > after the CIC? What is their purpose? Can’t we use just one > half-band? > 2) What is the purpose of the scale factor multiplication after > hb2? What does it compensate for? How do we decide its value? > > Thanks, > Francesco > _______________________________________________ > USRP-users mailing list > USRP-users@lists.ettus.com <mailto:USRP-users@lists.ettus.com> > http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com >