DSPRelated.com
Forums

Re: Re: Q-format ???

Started by Jeff Brower July 18, 2011
Pieter-

> i have a 2nd order IIR filter code for TMSC6x but there is some
> ambiguity while understanding this code. please help me to
> understand this code, which is given as to implement :
>
> y[n]*x[n]+b1*x[n-1]+b2*x[n-2]+a1 *y[n-1]+a2*y[n-2]

Where you appear to have inserted questions in the code, I've given a few comments
below, marked with [JB].

-Jeff

> % (Double precision)
> void iir_2nd_d(Shortword
> input[],Shortword den[],Shortword num[],
> Shortword output[],Shortword delin[],Shortword delout_hi[],
>
> Shortword delout_lo[],Shortword npts)
> {
> Shortword i,temp;
> Longword accum;
> //////////////// ist 5 line of for loop expanation required
> for (i = 0; i < npts; i++) {
> accum = L_mult(delout_lo[0],den[1]); %%what is delout_lo & delout_hi ??purpose?

[JB] delout_lo means "delay output, low half". The purpose is because the code has
been implemented for a 16-bit fixed-point device, and after each L_mac operation
(long multiply and accumulate), there is a 32-bit result. Probably the author wants
to maintain 32-bit intermediate precision, even though input, coefficients, and
output are 16-bit. Delay elements are internal only, so they can be maintained as
32-bit, which should improve numerical stability of the filter 2nd order section.

> accum = L_mac(accum,delout_lo[1],den[2]);
> accum = L_shr(accum,14); // why this shift ??? logic ??

[JB] The author wants to keep 18 bits of precision (i.e. discard 14) prior to the
next multiply-and-accumulate.

> accum = L_mac(accum,delout_hi[0],den[1]);
> accum = L_mac(accum,delout_hi[1],den[2]);
>
> accum = L_mac(accum,shr(input[i],1),num[0]);
> accum =L_mac(accum,delin[0],num[1]);
> accum = L_mac(accum,delin[1],num[2]);
>
> /* shift result to correct Q value */
> accum = L_shl(accum,2); /* assume coefficients in Q13 */ logic???

[JB] Probably accum has 3 sign bits at this point, for example after a Q14 x Q14
multiply (assuming an automatic 1-bit left shift in the L_mac() operation, which may
or may not be the case -- you need to check this), and the author wants to discard
the upper 2 sign bits.

> /* update input delay buffer */
> delin[1] = delin[0]; data_move();
> delin[0] = shr(input[i],1); data_move();
>
> /* update output delay buffer */
> delout_hi[1] = delout_hi[0]; data_move();
> delout_lo[1] = delout_lo[0]; data_move();
>
> delout_hi[0] = extract_h(accum);
> temp = shr(extract_l(accum),2);
> delout_lo[0] = temp & (Shortword)0x3FFF; logic();
>
> /* round off result */
> accum = L_shl(accum,1);
> output[i] = round(accum);
> }
> }

_____________________________________