Summary: You will implement band-pass finite impulse-response (FIR) filters with time-domain processing.
filter.asm1 .copy "core.asm" ; Copy in core file 2 ; This initializes DSP and jumps to "main" 3 4 FIR_len .set 8 ; This is an 8-tap filter. 5 6 .sect ".data" ; Flag following as data declarations 7 8 .align 16 ; Align to a multiple of 16 9 coef ; assign label "coeff" 10 .copy "coef.asm" ; Copy in coefficients 11 12 .align 16 13 firstate 14 .space 16*8 ; Allocate 8 words of storage for 15 ; filter state. 16 17 .sect ".text" ; Flag the following as program code 18 main 19 ; Initialize various pointers 20 stm #FIR_len,BK ; initialize circular buffer length 21 stm #coef,AR2 ; initialize coefficient pointer 22 stm #firstate,AR3 ; initialize state pointer 23 stm #1,AR0 ; initialize AR0 for pointer increment 24 25 loop 26 ; Wait for a new block of 64 samples to come in 27 WAITDATA 28 29 ; BlockLen = the number of samples that come from WAITDATA (64) 30 stm #BlockLen-1, BRC ; Put repeat count into repeat counter 31 rptb endblock-1 ; Repeat between here and 'endblock' 32 33 ld *AR6,16, A ; Receive ch1 into A accumulator 34 mar *+AR6(2) ; Rcv data is in every other channel 35 ld *AR6,16, B ; Receive ch2 into B accumulator 36 mar *+AR6(2) ; Rcv data is in every other channel 37 38 ld A,B ; Transfer A into B for safekeeping 39 40 ; The following code executes a single FIR filter. 41 42 sth A,*AR3+% ; store current input into state buffer 43 rptz A,(FIR_len-1) ; clear A and repeat 44 mac *AR2+0%,*AR3+0%,A ; multiply coef. by state & accumulate 45 46 rnd A ; Round off value in 'A' to 16 bits 47 48 ; end of FIR filter code. Output is in the high part of 'A.' 49 50 sth A, *AR7+ ; Store filter output (from A) into ch1 51 sth B, *AR7+ ; Store saved input (from B) into ch2 52 53 sth B, *AR7+ ; Store saved input to ch3...ch6 also 54 sth B, *AR7+ ; ch4 55 sth B, *AR7+ ; ch5 56 sth B, *AR7+ ; ch6 57 58 endblock: 59 b loop Figure 1 |
filter.asm applies an FIR filter to the signal
from input channel 1 and sends the resulting output to output
channel 1. It also sends the original signal to output
channel 2.
remez to generate this filter; you can type
help remez for more information. Use the
save_coef command to save each of these filters
into different files. (Make sure you reverse the vectors of
filter coefficients before you save them.) Also save your
filters as a MATLAB matrix, since you will need them later to
generate test vectors. This can be done using the MATLAB
save command. Once this is done, use the
freqz command to plot the frequency response of
each filter.
filter.asm to use the
coefficients for this filter by making several changes.
FIR_len to
20. FIR_len is set using the .set
directive, which assigns a number to a symbolic name. You will
need to change this to FIR_len .set 20.
.copy
directive brings in the correct coefficients. Change the
filename to point to the file that contains the coefficients
for your first filter.
.align and
.space directives appropriately. The TI
TMS320C54x DSP requires that circular buffers, which are used
for the FIR filter coefficient and state buffers, be aligned
so that they begin at an address that is a multiple of a power
of two greater than the length of the buffer. Since you are
using a 20-tap filter (which uses 20-element state and
coefficient buffers), the next greater power of two is 32.
Therefore, you will need to align both the state and
coefficient buffers to an address that is a multiple of 32.
(16-element buffers would also require alignment to a multiple
of 32.) This is done with the .align command. In
addition, memory must be reserved for the state buffer. This
is done using the .space directive, which takes
as its input the number of bits of space
to allocate. Therefore, to allocate 20 words of storage, use
the directive .space 16*20 as shown below:
1 .align 32 % Align to a multiple of 32
2 coef .copy "filter1.asm" % Copy FIR filter coefficients
3
4 .align 32 % Align to a multiple of 32
5 state .space 16*20 % Allocate 20 words of data space
PMST to
0xFFE0, reset the DSP, and run. Ensure that it
is has the correct frequency response. After you have verified
that this code works properly, proceed to the next step.
filter.asm
file from Part 1. Work from this
copy; do not modify your working filter from the previous
part. You will use that code again later.
.align and .copy
directives to load the second set of coefficients into data
memory. You will also need to add instructions to initialize
a pointer to the second set of coefficients and to perform the
calculations for the second filter.
AR4 and
AR5? Why is this more difficult? Renaming
AR4 and AR5 using the
.asg directive does not count!
firs instruction. Modify
your code from Part 1 to implement
the filter with a 4 kHz to 8 kHz passband using the
firs.
firs instruction
expects coefficients to be located in program memory instead
of data memory, and (2) firs requires the states
to be broken up into two separate circular buffers. Refer to
the firs instruction on page 4-59 in
the Mnemonic
Instruction Set manual, as well as a description and
example of its use on pages 4-5 through 4-8 of
the Applications
Guide for more information (Volumes 2 and
4 respectively of the TMS320C54x DSP Reference
Set).
AR0 needs to be set to -1 for this code to work properly. Why?
COEFF is a label to the
coefficients now expected to be in program memory. Refer to the
firs description for more
information).
1 mvdd *AR2,*AR3+0% ; write x(-N/2) over x(-N)
2 sth A,*AR2 ; write x(0) over x(-N/2)
3 add *AR2+0%,*AR3+0%,A ; add x(0) and x(-(N-1))
4 ; (prepare for first multiply)
5
6 rptz B,#(FIR_len/2-1)
7 firs *AR2+0%,*AR3+0%,COEFF
8 mar ??????? ; Fill in these two instructions
9 mar ??????? ; They modify AR2 and AR3.
10
11 ; note that the result is now in the
12 ; B accumulator
1 stm #(FIR_len/2),BK ; initialize circular buffer length
2 stm #firstate_,AR2 ; initialize location containing first
3 ; half of states
4
5 stm #-1,AR0 ; Initialize AR0 to -1
6
7 stm #firstate2_,AR3 ; initialize location containing last half
mac instruction. Are the results the same? Why or
why not? Ensure that the filtered output is sent to output
channel 1, and that the unmodified output is still sent to
output channel 2.