📄 fir_blk.asm
字号:
/**************************************************************
File Name: fir_blk.asm
Date Modified: 2/16/99 RFG
7/17/00 PPG
Purpose: Subroutine that implements a Block FIR Filter given
coefficients and samples.
Equation: y(n) = Summation from k=0 to M of h(k)*x(n-k)
Calling Parameters:
b0,i0 = address of delay line buffer
l0 = length of delay line buffer
b1,i1 = address of input samples buffer
b8,i8 = address of coefficients buffer
l8 = length of coefficients buffer
b9,i9 = address of output buffer
r1 = number of taps in the filter divided by 2
r2 = number of samples
r3 = (number of taps in filter - 6) / 2
s0,m0,l1,l9 = 0
m1,m10 = 1
m2=-1
m3,m9 = 2
Assumptions:
All arrays must start on even address boundaries.
All arrays must have an even number length (zero
pad if necessary)
Return Values:
i9=OUTPUT
Registers Affected:
f0,s0,f4,s4,f8,s8,f12,s12
i0,i8,i9
Cycle Count:
9 + taps/2 + samples(6 + taps/2) + 9 cache misses
Number of PM Locations:
21 instruction words
2 * Number of taps locations for coefficients
Number of samples + 1 locations for the output buffer
Number of DM Locations:
Number of taps locations for the delay line buffer
Number of samples locations for the input buffer
Circular buffer notes:
Because SIMD or Long word access transfer two 32-bit words, programs must be
careful when using these accesses in circular buffering. It is important that
SIMD or Long word accesses do not cross a circular buffer boundary. If a SIMD
mode access occurs using a circular buffer index register that points to the
last location in the circular buffer (end of buffer), the resulting access
transfers the last location in the circular buffer and the
first location outside the buffer (end of buffer + 1).
**************************************************************/
#include "def21160.h"
.global fir;
/* program memory code */
.section/pm seg_pmco;
fir:
/* Circular Buffer Enable, SIMD Mode Enable */
bit set MODE1 CBUFEN | PEYEN;
r0 = dm(i1,m1); /* read one sample from INPUT[i] */
/* SIMD not in effect until next cycle */
/* clear delay line */
f8=0.0;
lcntr = r1, do clear_fir until lce;
clear_fir: dm(i0,m3) = f8;
f4 = pm(i8,m9); /* read 2 coeffs */
lcntr = r2, do main_fir until lce; /* outer loop - sample loop */
dm(i0,m3)=f0, pm(i9,m10)=f8; /* transfer sample to delayline, write result to OUTPUT[i] */
f8=f0*f4, f0=dm(i0,m3), f4=pm(i8,m9); /* samples * coeffs, read 2 samples, read 2 coeffs */
f12=f0*f4, f0=dm(i0,m3), f4=pm(i8,m9); /* samples * coeffs, read 2 samples, read 2 coeffs */
lcntr=r3, do macs until lce; /* FIR loop */
macs: f12=f0*f4, f8=f8+f12, f0=dm(i0,m3), f4=pm(i8,m9); /* samples * coeffs, accum, read 2 samples, read 2 coeffs */
f12=f0*f4, f8=f8+f12, s0=dm(i0,m2); /* samples * coeffs, accum, dummy read to move pointer to oldest sample */
f8=f8+f12, s10=dm(i1,m1); /* final SIMD accum, read new sample */
r12=s8; /* move PEy total into PEx register file */
f8=f8+f12, f0=dm(i0,m0), f4=pm(i8,m9); /* last accum, read sample into s0 for first MAC of next sample, read 2 coeffs */
main_fir: f0 <-> s10; /* place new sample in s0 */
rts (db);
/* Circular Buffer Disable, SIMD Mode Disable */
bit clr MODE1 CBUFEN | PEYEN;
pm(i9,m10)=f8;
fir.end:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -