Name: LATGEN.ASM Type: Assembler Macro Version: 1.0 Last Change: 8-Aug-86 Description: Lattice FIR Filter Assembler Macro A general form of the lattice filter is show in Figure 6. A >---->(+)------------>(+)----------->(+)---------->---| (in) ^ / ^ / ^ / | \ k3 \ k2 \ k1 | \ / \ / \ / | / / / V / \ / \ / \ | / \ / \ / \ | / -k3 / -k2 / -k1 | v | v | v | | -----(+)<------1/z---(+)<-----1/z---(+)<-------1/z---| | | | | v3 v2 v1 v0 | \____ ____/ | \ \ / / -----------------------(+)-------------------- |________ A (out) Figure 6 The k and v coefficients can be obtained from a direct form filter. For the filter shown, the pointers R0 and R4 are initialized to point as shown: r0 r4 | | v v x: k3 k2 k1 v3 v2 v1 v0 y: s4 s3 s2 s1 m0=6 (=2*order, mod 7) m4=3 (=order, mod 4) The register R0 is initialized to point to the first k coefficient (k3) and the pointer R4 initially points to the first location allocated for the state variables. The modulo register m0 is set to two times the number of k coefficients (6 in this example) and the register m4 is set to the number of coefficients (3 in this example). The input sample is put in register A and the filter macro is then called as: latgen order ;call filter where 'order' is the number of k coefficients in the lattice. FILTER OPERATION The operation of this filter is similar to the operation of the all pole filter described previously (latiir) and can be described (refer to Figure 6 and the macro 'latgen'): 1. The input sample is assumed to be in register A. 2. The first MOVE loads the first k coefficient (k3) and increments the pointer R0 to point to the next k coefficient. Similarly, the state variable is loaded and the pointer R4 is decremented to point to the previous state variable. The previous state variable is actually the value that v3 was multiplied by on the previous sample time. This value is not needed and can be overwritten. 3. The DO loop now will perform ORDER passes to calculate the new state variables. 4. The first MACR will calculate the top value by subtracting from the value in A the product of k (X0) and the state (Y0). The previous state calculated (B) is now saved and the pointer R4 is incremented to point back to the current state value. Note that the B register initially has an unknown value so the first pass of the loop saves an unknown value. 5. The top A value is then moved to a product register (X1) so that it can later be multiplied. The B register is loaded with the current state variable and then the pointer to the state variables (R4) is incremented to point to the next state variable. 6. The new state is calculated by adding to the current state variable (B) the product of the top value (X1) and the k coefficient (X0). 7. The loop is now complete and has calculated and saved ORDER-1 of the state variables. (ORDER+1 values are needed to calculate the v coefficient taps). 8. The output is then rounded, the second last state is saved and the pointer R4 is incremented to point to the next unused state variable. Note that at this point that R4 is pointing to the unknown value that was first written in the loop. 9. The value in A is saved as the state variable and the pointer R4 is incremented to point to the next state variable. At this point, R4 points to the state to multiply V3. The A register is also cleared to later accumulate the FIR taps. 10. The state pointed to by R4 is then loaded into product register Y0. 11. The FIR taps are calculated by using a REP instruction to calculate ORDER number of taps. Note that the first tap coefficient V3 was loaded by the last instruction of the DO loop. 12. The FIR taps are then calculated. All except for the last tap are calculated. 13. The last tap is then calculated and rounded and the pointer R4 is incremented to point to the next state variable. This state variable was the second state variable calculated by the loop. The first state variable calculated is only needed to multiply v3 and is not needed at the next sample time. Benchmarks for this filter are: 12 instructions, 4N+9 instruction cycles. The test program 'latgent.asm' in the DSPLIB gives an example of how to call this filter.