Name: LATIIR.ASM Type: Assembler Macro Version: 1.0 Last Change: 31-Jul-86 Description: Lattice IIR Filter Assembler Macro BACKGROUND The filter described here is an all pole lattice filter. The basic section of a IIR lattice filter is show in Figure 4 . >--------------(+)------------------------> X(z)B[j](z) ^ | X(z)B[j-1](z) ------------- \ / --------------- B[L](z) -k / B[L](z) \ / / / \ zX(z)C[j](z) k \ zX(z)C[j-1](z) -------------- / \ ---------------- B[L](z) v | B[L](z) <--------------(+)----------------1/z-----< Figure 4 IMPLEMENTATION A third order all pole lattice IIR filter is shown in Figure 5. A >---->(+)------------>(+)----------->(+)---------->----> A (in) ^ / ^ / ^ / | (out) \ k3 \ k2 \ k1 | \ / \ / \ / | / / / V / \ / \ / \ | / \ / \ / \ | / -k3 / -k2 / -k1 | v | v | v | | --(+)<------1/z---(+)<-----1/z---(+)<-------1/z--| S3 S2 S1 Figure 5 For the filter shown, the pointers R0 and R4 are initialized to point to the buffers as shown: R0 R4 | | v v x: k1 k2 k3 y: s1 s2 s3 M0=2 (mod 3) M4=2 (mod 3) The modulo registers are set to the number of coefficients in the filter minus one (in this example there are three coefficients). The input sample is put in the A register and then the filter macro is called. The result of the filtering operation is in A. The output from the bottom left is not saved or calculated. To use the filter, it is assumed the registers R0, R4, M0 and M4 have been properly initialized. The input sample is in register A and the filter is called as: latiir order ;call fir lattice filter where 'latfir' is the macro name and 'order' is the number of reflection coefficients. FILTER OPERATION The operation of this filter can be described (refer to Figure 5 and the macro 'latiir'): 1. Assume the input sample is in register A and the pointers R0 and R4 are properly set. The value at the bottom left of Figure 5 is not needed so in this implementation of the filter it is not calculated. 2. The first MOVE loads the first k (k3) into product register X0, and decrements the pointer R0 to the next coefficient. Simultaneously, the filter state is loaded and the pointer R4 is incremented to point to the next state. 3. The first section of the filter is computed by the MAC instruction. The coefficient k (X0) is multiplied by the state (Y0) and the result is subtracted from the input value (A). The next k coefficient (k2) is then loaded into X0 and the pointer R0 is again decremented. The next state is the loaded into Y0 and the pointer R4 is then decremented to point back to the previous state. Now, R4 points back to the state that was used in the previous instruction. Since that value is no longer needed, the new state computed will be stored in that location. 4. The DO loop now calculates the remaining filter sections. Since the first section was calculated outside of the loop, only ORDER-1 passes remain. 5. The first MAC of the loop updates the A value by subtracting the product of the coefficient (X0) and the state (Y0). The new state calculated (B) is saved in the previously used state position and the pointer R4 is incremented to point to the current state position. It should be noted that at this time, the previous state has not been calculated so the first value that is written is unknown. 6. The top A value is moved into a product register (X1) so it can be multiplied by the k coefficient (x0). The current state pointed to by R4 is reloaded and R4 is incremented to point to the next state. 7. The new state is now calculated by adding the product of the top value (A) and the k coefficient (X0) to the current state value (B). A new k coefficient is loaded and the pointer R0 is decremented to point to the next k coefficient. The next state is loaded and the pointer R4 is decremented to point to the previously used state. At this point it should be observed that the next pass of the loop will save the new state (B) that was just calculated. 8. Upon exiting from the loop, the output value is rounded, the second last state is saved and the state pointer R4 is incremented. 9. The pointer to the k coefficients is incremented by using a dummy load. Since the pointer R0 is decremented 2 times before entering the loop and the loop decrements it ORDER-1 times, the net number of decrements is ORDER+1. Since there are ORDER number of coefficients and the storage is modulo ORDER, the pointer must be incremented to point to the k3 again. The output value in A is also saved as the last state and the pointer R4 is incremented to the next location. It is interesting to note that at this point, the value in A was saved over the unknown value in the state buffer that was written in the first pass of the loop. The state pointer R4 then points to the next state which is the first state used on the next sample time. The benchmarks for this filter are: 9 instructions, 3N+4 instruction cycles, 2 stack locations.