📄 fir_fr16_.asm
字号:
/*******************************************************************************************
Copyright(c) 2000 Analog Devices Inc.
********************************************************************************************
File Name : fir_fr16.asm
Function Name : __fir
Module Name : FILTER Library
Description : This function performs FIR filter operation on given input.
Operands : R0- Address of input vector, R1-Address of output vector, R2- Number of input elements
Filter structure is on stack.
Prototype:
void fir(const fract16 x[],fract16 y[],int n,fir_state_fr16 *s);
Structure of fir_state_fr16:
{
fract16 *h, // filter coefficients
fract16 *d, // start of delay line
fract16 *p, // read/write pointer
int k, // no. of coefficients
int l // interpolation/decimation index
} fir_state_fr16;
Registers used :
R0, R1, R2, R3, R3, R4, R5, R6
I0 -> Address of delay line (used for updating the delay line)
I1 -> Address of delay line (used for fetching the delay line data)
I2 -> Address of filter coeff. h0, h1 , ... , hn-1
I3 -> Address of output array y[]
P0 -> Address of input array x[]
P1, P2, P3
P5 -> Address of structure s
Code size: 354 bytes
____________________________________________________________________________
Computation time:
a) Even Taps, Even no. inputs : 64 + Ni/2*(3 + Nc)
For Ni=256, L=8 : 1472
b) Odd Taps, Even no. inputs : 70 + Ni/2*(3 + Nc)
For Ni=256, L=9 : 1606
c) Even Taps, Odd no. inputs : 64 + (Ni-1)/2*(3 + Nc) + Nc
For Ni=257, L=8 : 1480
d) Odd Taps, Odd no. inputs : 73 + (Ni-1)/2*(3 + Nc) + Nc
For Ni=257, L=9 : 1618
_______________________________________________________________________________
********************************************************************************************/
.section program;
.global __fir_fr16;
.align 8;
__fir_fr16:
[--SP]=(R7:4,P5:3);//PUSH R7-R4,P5-P3 ON STACK
P5=[SP+40]; // ADDRESS OF FILTER STRUCTURE
P0=R0; // ADDRESS OF INPUT ARRAY
I3=R1; // ADDRESS OF OUTPUT ARRAY
CC=R2<=0; // CHECK IF NUMBER OF INPUT ELEMENTS<=0
P1=[P5++]; // POINTER TO FILTER COEFFICIENTS
P2=[P5++]; // POINTER TO DELAY LINE
P3=[P5++]; // ADDRESS TO READ/WRITE POINTER
R1=[P5--]; // NUMBER OF COEFFICIENTS
IF CC JUMP _fir_fr16_RET_END;
CC=R1<=0; // CHECK IF NUMBER OF COEFF. <=0
IF CC JUMP _fir_fr16_RET_END;
R5=R1; // STORE NUMBER OF FILTER COEFF. IN R5
R1=R1+R1; // DOUBLE R1 TO INCREMENT AS HALF WORD
I2=P1; // INITIALISE I2 TO FILTER COEFF. ARRAY
B2=P1; // MAKE FILTER COEFFS. AS CIRCULAR BUFFER
L2=R1;
I1=P3; // INDEX TO READ/WRITE POINTER
B1=P2; // INITIALISE B1 AND L1
L1=R1; // FOR DELAY LINE CIRCULAR BUFFER
I0=P3; // INDEX TO READ/WRITE POINTER
B0=P2; // INITIALISE B0 AND L0
L0=R1; // FOR DELAY LINE CIRCULAR BUFFER
P1=R2; // SET OUTER LOOP COUNTER
P2=R5; // SET INNER LOOP COUNTER
L3 = 0;
R6=PACK(R2.H,R2.L)||I1+=4;
CC=R6==1;
IF CC JUMP _fir_fr16_SING_SAMP;
CC=BITTST(R5,0); //Check if the number of filter taps are odd
M0=6;
P2+=-1; //Nc-1
IF CC JUMP _fir_fr16_FIR_ODD;//Odd tap FIR
#ifdef __CSYNC_DEFINED__
CSYNC;
#endif
/***************************************************************************************************************/
/**Even number of input samples**/
/**Even number of filter taps**/
I0+=2 || R0.L=W[I1++];
R0=[P0++] || R2=[I2++];
LSETUP(_fir_fr16_E_FIR_START,_fir_fr16_E_FIR_END) LC0=P1>>1; //Loop 1 to Ni/2
_fir_fr16_E_FIR_START:
A1=R0.H*R2.L,A0=R0.L*R2.L ||I1-=2 || W[I0--]=R0.L;
R4=PACK(R0.H,R4.L) || R0.H=W[I1++] || NOP;
LSETUP(_fir_fr16_E_MAC_ST,_fir_fr16_E_MAC_END)LC1=P2>>1;//Loop 1 to Nc-1/2
_fir_fr16_E_MAC_ST: A1+=R0.L*R2.H,A0+=R0.H*R2.H || R2.L=W[I2++] || R0.L=W[I1++];
_fir_fr16_E_MAC_END: A1+=R0.H*R2.L,A0+=R0.L*R2.L || R0.H=W[I1++] || R2.H=W[I2++];
R3.H=(A1+=R0.L*R2.H),R3.L=(A0+=R0.H*R2.H) (T) || R0=[P0++] || W[I0--]=R4.H;
_fir_fr16_E_FIR_END:R2=[I2++] || [I3++]=R3;
P2+=-2;
R0.L=W[I0--] || I2-=4;
R0=I0;
I0+=2 || R2.L=W[I1--];
P0+=-4;
JUMP _fir_fr16_DATA;
/***************************************************************************************************************/
/***************************************************************************************************************/
/**Even number of input samples**/
/**Odd number of filter taps**/
_fir_fr16_FIR_ODD: P2+=-1; //Nc-2
B3=I3;
R2 = R2 >>1 || R4.H=W[I0];
R2=R2 << 2;
R5=[P0];
L3=R2;
R6.H=W[I1++] ||I3-=4;
R3=[I3] || R2=[I2++];
LSETUP(_fir_fr16_O_FIR_START,_fir_fr16_O_FIR_END) LC0=P1>>1; //Loop 1 to Ni/2
_fir_fr16_O_FIR_START:
R0=PACK(R6.H,R5.L) || R7=[P0++] || W[I0++]=R5.H ;
A1=R5.H*R2.L,A0=R5.L*R2.L || W[I0--]=R5.L;
LSETUP(_fir_fr16_O_MAC_ST,_fir_fr16_O_MAC_END)LC1=P2>>1;//Loop 1 to Nc/2-1
_fir_fr16_O_MAC_ST: A1+=R0.L*R2.H,A0+=R0.H*R2.H || R2=[I2++] || R0.L=W[I1++];
_fir_fr16_O_MAC_END:A1+=R0.H*R2.L,A0+=R0.L*R2.L || R0.H=W[I1++]|| R5=[P0];
A1+=R0.L*R2.H,A0+=R0.H*R2.H || R2.H=W[I2++] || R6.H=W[I1++] ;//Done only for Odd number of filter coeff.
R3.L=(A0+=R4.H*R2.H) (T) || I0-=4 || [I3++]=R3 ;
_fir_fr16_O_FIR_END:R3.H=(A1+=R0.H*R2.H) (T) || R2=[I2++] || R4.H=W[I0];
L3 = 0;
R0=I0;
R2.L=W[I0--] || I2-=4;
[I3++]=R3||I1-=2;
/***************************************************************************************************************/
_fir_fr16_DATA: CC=BITTST(R6,0);
IF !CC JUMP _fir_fr16_RET_END1;//If even number of input samples, jump to ret_end
/***************************************************************************************************************/
/**For Odd number of input samples process the last sample separately**/
P2+=2;
_fir_fr16_SING_SAMP: A1=A0=0 || R0=W[P0] (Z) || R2.L=W[I2++];
R4=W[P0](Z) || R2.H=W[I0++];
LSETUP(_fir_fr16_L_MAC_ST,_fir_fr16_L_MAC_ST)LC1=P2;//Loop 1 to Nc
_fir_fr16_L_MAC_ST:R3.L=(A0+=R0.L*R2.L) (T) || R2.L=W[I2++] || R0.L=W[I1++];
W[I0--]=R4.L;
W[I3++]=R3.L || I0-=2;
R0=I0;
_fir_fr16_RET_END1: [P5]=R0;
/**************************************************************************************************************/
_fir_fr16_RET_END:
L0=0;
L1=0;
L2=0;
(R7:4,P5:3)=[SP++]; //POP R7-R4,P5-P3 FROM STACK
RTS;
.__fir_fr16.end:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -