I'm a beginner when it comes to DSP but I need to learn how to

implement basic filters on a DSP board. I'm using an ADSP-21369 EZ-Kit

from Analog Devices. I understand how to generate coefficients using

Matlab but how to I use these coefficients to filter my input signal.

Can someone explain using either code or just an explanation. Any help

will be greatly appreciated.

# Basic Filter Implementation

Started by ●March 4, 2007

Reply by ●March 5, 20072007-03-05

Dan wrote:

> I'm a beginner when it comes to DSP but I need to learn how to

> implement basic filters on a DSP board. I'm using an ADSP-21369 EZ-Kit

> from Analog Devices. I understand how to generate coefficients using

> Matlab but how to I use these coefficients to filter my input signal.

> Can someone explain using either code or just an explanation. Any help

> will be greatly appreciated.

Can't demonstrate with code as I've never used this processor.

I'll assume you're talking about implementing a plain FIR filter

without anything fancy like decimation or interpolation, half

banded filters etc..

Implementation is quite simple.

1- Calculate filter impulse response and store the resulting

N coefficients in a table. It can help if this table is

circular, but it's not strictly necessary if the processor

address address alignment constraints on circular buffers

(some do).

2 - For each signal channel to be filtered you need this state

which must persist between samples (filter invocations)

A - A circular buffer of N previous samples (typically initialised

to all zeros).

B - A pointer to this buffer, initialised to start of the buffer.

Then for each input sample you..

1 - Write the sample to the circular buffer and post increment

the buffer pointer (using circular addressing). The pointer

will now be pointing to the *oldest* sample in the buffer.

2 - Initialise a pointer to the start of the N coefficient table.

3 - Initialise an accumulator to 0.

4 - Repeat N times

Read sample from circular buffer and post increment circular

buffer pointer (using circular addressing).

Read coefficient from coeficient table and post increment

coefficient pointer.

Multiply sample by coefficient and add to accumulator

5 - The accumulator will now contain the filtered output

sample. Also, note that circular buffer pointer has been

incremented (N+1) times in total. (I.E. it has been advanced

1 place (N+1 MOD N = 1), so again points to the oldest sample

which will be overwritten by the next input sample.

If you're using circular addressing for the coefficients then

this pointer has been advanced N times so should point to

the start of the table again (does not need re-initialising

if you're processing several input samples in 1 batch).

6 - If this is the last input sample in the current batch then

save the current circular buffer pointer.

Note:

1- Strictly what I've just described performs a correlation, not

a convolution (impulse response will be coefficient table

reversed). For symetric FIR's (most are) this will not matter.

If the desired impulse response is asymetric then you need

to reverse the coefficient table.

2- Lots of detail about word lengths, scaling, saturation, rounding

and fractional arithmetic ommited.

3- You should be able to get the loop described in 4 down to

1 instruction per coef (filter tap). Typical DSP pseudo

code would look like this..

accum=0, sample=buffPtr++, coef=coefPtr++; // preload

Repeat N-1 times; // Not N!!

accumcum+sample*coef, sample=buffPtr++, coef=coefPtr++; // 1 instr!

accumcum+sample*coef; // Final step

HTH

Regards

--

Adrian Hey

> I'm a beginner when it comes to DSP but I need to learn how to

> implement basic filters on a DSP board. I'm using an ADSP-21369 EZ-Kit

> from Analog Devices. I understand how to generate coefficients using

> Matlab but how to I use these coefficients to filter my input signal.

> Can someone explain using either code or just an explanation. Any help

> will be greatly appreciated.

Can't demonstrate with code as I've never used this processor.

I'll assume you're talking about implementing a plain FIR filter

without anything fancy like decimation or interpolation, half

banded filters etc..

Implementation is quite simple.

1- Calculate filter impulse response and store the resulting

N coefficients in a table. It can help if this table is

circular, but it's not strictly necessary if the processor

address address alignment constraints on circular buffers

(some do).

2 - For each signal channel to be filtered you need this state

which must persist between samples (filter invocations)

A - A circular buffer of N previous samples (typically initialised

to all zeros).

B - A pointer to this buffer, initialised to start of the buffer.

Then for each input sample you..

1 - Write the sample to the circular buffer and post increment

the buffer pointer (using circular addressing). The pointer

will now be pointing to the *oldest* sample in the buffer.

2 - Initialise a pointer to the start of the N coefficient table.

3 - Initialise an accumulator to 0.

4 - Repeat N times

Read sample from circular buffer and post increment circular

buffer pointer (using circular addressing).

Read coefficient from coeficient table and post increment

coefficient pointer.

Multiply sample by coefficient and add to accumulator

5 - The accumulator will now contain the filtered output

sample. Also, note that circular buffer pointer has been

incremented (N+1) times in total. (I.E. it has been advanced

1 place (N+1 MOD N = 1), so again points to the oldest sample

which will be overwritten by the next input sample.

If you're using circular addressing for the coefficients then

this pointer has been advanced N times so should point to

the start of the table again (does not need re-initialising

if you're processing several input samples in 1 batch).

6 - If this is the last input sample in the current batch then

save the current circular buffer pointer.

Note:

1- Strictly what I've just described performs a correlation, not

a convolution (impulse response will be coefficient table

reversed). For symetric FIR's (most are) this will not matter.

If the desired impulse response is asymetric then you need

to reverse the coefficient table.

2- Lots of detail about word lengths, scaling, saturation, rounding

and fractional arithmetic ommited.

3- You should be able to get the loop described in 4 down to

1 instruction per coef (filter tap). Typical DSP pseudo

code would look like this..

accum=0, sample=buffPtr++, coef=coefPtr++; // preload

Repeat N-1 times; // Not N!!

accumcum+sample*coef, sample=buffPtr++, coef=coefPtr++; // 1 instr!

accumcum+sample*coef; // Final step

HTH

Regards

--

Adrian Hey

Reply by ●March 5, 20072007-03-05

On Sun, 4 Mar 2007, Dan wrote:

> I'm a beginner when it comes to DSP but I need to learn how to

> implement basic filters on a DSP board. I'm using an ADSP-21369 EZ-Kit

> from Analog Devices. I understand how to generate coefficients using

> Matlab but how to I use these coefficients to filter my input signal.

> Can someone explain using either code or just an explanation. Any help

> will be greatly appreciated.

If it's an FIR you can use a standard subroutine with one vector coming

from Matlab and one vector coming from your input data. Use circular

buffers and change the input data pointer but not the filter data pointer.

The standard subroutine should do the multiply/sum for you.

The main trick is to ensure it's a circular buffer. Sometimes that just

easier to do in assembler - but I'm sure there's others here who can

explain all the #pragma's it takes to get circular to work in C. With a

circular buffer, you just add one data value, change the starting point of

the buffer, and go.

To input the data file, either use a #include or set up the

.var filt_coef="filename"; form in assembler. Lots of people here can

fill in details (I usually use assembler and brute force, so I'm not much

help :-)

Patience, persistence, truth,

Dr. mike

> I'm a beginner when it comes to DSP but I need to learn how to

> implement basic filters on a DSP board. I'm using an ADSP-21369 EZ-Kit

> from Analog Devices. I understand how to generate coefficients using

> Matlab but how to I use these coefficients to filter my input signal.

> Can someone explain using either code or just an explanation. Any help

> will be greatly appreciated.

If it's an FIR you can use a standard subroutine with one vector coming

from Matlab and one vector coming from your input data. Use circular

buffers and change the input data pointer but not the filter data pointer.

The standard subroutine should do the multiply/sum for you.

The main trick is to ensure it's a circular buffer. Sometimes that just

easier to do in assembler - but I'm sure there's others here who can

explain all the #pragma's it takes to get circular to work in C. With a

circular buffer, you just add one data value, change the starting point of

the buffer, and go.

To input the data file, either use a #include or set up the

.var filt_coef="filename"; form in assembler. Lots of people here can

fill in details (I usually use assembler and brute force, so I'm not much

help :-)

Patience, persistence, truth,

Dr. mike

Reply by ●March 5, 20072007-03-05

Dan wrote:

>

> I'm a beginner when it comes to DSP but I need to learn how to

> implement basic filters on a DSP board. I'm using an ADSP-21369 EZ-Kit

> from Analog Devices. I understand how to generate coefficients using

> Matlab but how to I use these coefficients to filter my input signal.

> Can someone explain using either code or just an explanation. Any help

> will be greatly appreciated.

Download optimized 21369 filter code from the ADI website:

http://www.analog.com/processors/sharc/technicalLibrary/codeExamples/213

6x_simd_code.html

Regards,

Andor

>

> I'm a beginner when it comes to DSP but I need to learn how to

> implement basic filters on a DSP board. I'm using an ADSP-21369 EZ-Kit

> from Analog Devices. I understand how to generate coefficients using

> Matlab but how to I use these coefficients to filter my input signal.

> Can someone explain using either code or just an explanation. Any help

> will be greatly appreciated.

Download optimized 21369 filter code from the ADI website:

http://www.analog.com/processors/sharc/technicalLibrary/codeExamples/213

6x_simd_code.html

Regards,

Andor