?? fft32.asm
字號:
/* fft32.asm
July 2004 PM
This is assembly routine for the Complex radix-2 C-callable FFT on TigerSHARC
family of DSPs only. It elaborates on complex only inputs. The real case has been excluded
I. Description of Calling.
1. Inputs:
j4 -> input (ping-pong buffer 1)
j5 -> ping-pong buffer 1
j6 -> ping-pong buffer 2
j7 -> output
//j27+0x18 -> N = Number of points
2. C-Calling Example:
fft32(&(input), &(ping_pong_buffer1), &(ping_pong_buffer2), &(output), N);
3. Limitations:
a. All buffers must be aligned on memory boundary which is a multiple of 4.
b. N must be between 32 and MAX_FFT_SIZE.
c. If memory space savings are required and input does not have to be
preserved, ping_pong_buffer1 can be the same buffer as input.
d. If memory space savings are required, output can be the same buffer
as ping_pong_buffer2 if the number of FFT stages is even (i.e.
Log2(N) is even) or the same as ping_pong_buffer1 if the number of
FFT stages is odd (i.e. Log2(N) is odd).
4. MAX_FFT_SIZE can be selected via #define. Larger values allow for more choices
of N, but its twiddles will occupy more memory.
5. This C - callable function can process up to 64K blocks of data on TS201
(16K blocks on TS101) because C environment itself necessitates memory.
Therefore, if more input points are necessary, assembly language development
may become a must. On TS201, a block of memory is 128K words long, so
maximum N is 64K complex points. TS101 contains only 2 blocks of data memory
of 64K words and 4 buffers must be accommodated.
Therefore, maximum N is 16K complex words.
II. Description of the FFT algorithm.
1. The input data is treated as complex interleaved N-point.
2. Due to re-ordering, no stage can be done in-place.
3. The bit reversal and the first two stages are combined into
a single loop. This loop takes data from input and stores it
in the ping-pong buffer1.
4. Each subsequent stage ping-pongs the data between the two ping-pong
buffers. The last stage uses FFT output buffer for its output.
5. Although the FFT is designed to be called with any point size
N <= MAX_FFT_SIZE by subsampling the twiddle factors, for ADSP-TS20x
processors, the best cycle optimization is achieved when MAX_FFT_SIZE=N.
For ADSP-TS101 all choices of MAX_FFT_SIZE are equally optimal.
III.For all additional details regarding this algorithm and code, see EE-218
application note, available from the ADI web site.
*/
//************************************ Includes **********************************
/*
#define mPUSHQ(arg) \
Q[k27 += -4] = arg;;
#define mPOPQ(arg) \
k27 = k27 + 4;; \
arg = Q[k27 += 0];;
#define mENTER \
j26 = j27 - 0x40; k26 = k27 - 0x40;; \
[j27 += 0xFFFFFFF4] = cJMP; k27 = k27 - 0x04;;
#define mRETURN \
cjmp = [j26 + 0x40];; \
cjmp(ABS)(NP); j27:24 = Q[j26 + 0x44]; k27:24 = Q[k26 + 0x44];;
*/
//************************* Externs *************************************
#include "SS_SYN.h"
//#include "FFTDef.h"
#ifdef __ADSPTS201__
#include "defts201.h"
#endif
//********************************* FFT Routine *********************************
.section program;
.global _FFT32;
//.extern _twiddles;
.align_code 4;
_FFT32:
// j4 =FFT_input;;
// j5 =ping_pong_buffer1;;
// j6 =ping_pong_buffer2;;
// j7 =FFT_output;;
// k4 =_twiddles;;
//********************************** Prologue ***********************************
/*
mENTER
mPUSHQ(xR31:28)
mPUSHQ(xR27:24)
mPUSHQ(yR31:28)
mPUSHQ(yR27:24)
*/
[j27+=4]= cjmp ; [k27+=4]= yr0 ;;
[j27+=4]= lc0 ; [k27+=4]= yr0 ;;
[j27+=4]= lc1 ; [k27+=4]= yr0 ;;
[j27+=4]= jl0 ; [k27+=4]= kl0 ;;
[j27+=4]= jb0 ; [k27+=4]= kb0 ;;
q[j27+=4]= xr3:0 ; q[k27+=4]= yr3:0 ;;
q[j27+=4]= xr7:4 ; q[k27+=4]= yr7:4 ;;
q[j27+=4]= xr11:8 ; q[k27+=4]= yr11:8 ;;
q[j27+=4]=xr15:12 ; q[k27+=4]=yr15:12 ;;
q[j27+=4]=xr19:16 ; q[k27+=4]=yr19:16 ;;
q[j27+=4]=xr23:20 ; q[k27+=4]=yr23:20 ;;
q[j27+=4]= j3:0 ; q[k27+=4]= k3:0 ;;
q[j27+=4]= j11:8 ; q[k27+=4]= k11:8 ;;
//************************************ Setup *************************************
_FFTStages1and2:
//j11 = [j27 + 0x18];; // j11=N
j11=FFT_size;;
//xr3=j11; k7=k31+_twiddles;;
xr3=j11; k7=k31+k4;;
k1=j11; j8=lshiftr j11;; // k1=N, j8=N/2
j9=lshiftr j8; xr0=MAX_FFT_SIZE; xr3=LD0 r3;; // j9=N/4, compute the twiddle stride
k8=lshiftr k1; xr0=LD0 r0; xr1=j11;;
k8=lshiftr k8; xr1=LD0 r1; xr2=(31-3);; // k8=N/4, Compute Stages-3
k0=j4; k10=lshiftr k8; xr1=r1-r0; xr0=lshift r0 by -32;; // k0->input, xr1=bit difference between MAX and N
k10=lshiftr k10; xr0=bset r0 by r1; xr30=r2-r3;; // k10=N/16, xr30=Stages-3
k10=k10-1; xr0=lshift r0 by 2; LC1=xr30;; // k10=N/16-1, LC1=Stages-3
k9=xr0; k4=k31+(MAX_FFT_SIZE/4-1);;
k4=not k4; j10=lshiftr j9;; // initial twiddles pointer mask, j10=N/8
//****************** Bit Reverse and Stages 1 & 2 ******************************
k5=lshiftr k1;; // k5=N/2
j0=j31+j6; k6=k6-k6;; // j0->ping_pong_buffer2
j1=j0+j9; LC0=k10;; // j1->ping_pong_buffer2+N/4, LC0=N/16-1
j2=j1+j9; k1=k0+k5;; // j2->ping_pong_buffer2+N/2, k1->input+N/2
j3=j2+j9; k2=k1+k5;; // j3->ping_pong_buffer2+3N/4, k2->input+N
j12=j3+j9; k3=k2+k5;; // j12->ping_pong_buffer2+N, k3->input+3N/2
j13=j12+j9; k5=lshiftr k5;; // j13->ping_pong_buffer2+5N/4, k5=N/4
j14=j13+j9; r1:0=q[k0+k6];; // j14->ping_pong_buffer2+3N/2
j15=j14+j9; r3:2=q[k2+k6];; // j15->ping_pong_buffer2+7N/4
r5:4=q[k1+k6];;
r7:6=q[k3+k6];;
k6=k6+k5 (br); fr0=r0+r2, fr20=r0-r2;;
r9:8=q[k0+k6]; fr2=r1+r3, fr29=r1-r3;;
r11:10=q[k2+k6]; fr4=r4+r6, fr21=r4-r6;;
r13:12=q[k1+k6]; fr5=r5+r7, fr28=r5-r7;;
r15:14=q[k3+k6]; fr18=r8+r10, fr22=r8-r10;;
k6=k6+k5 (br); fr19=r9+r11, fr31=r9-r11;;
fr26=r12+r14, fr23=r12-r14;;
fr27=r13+r15, fr30=r13-r15;;
fr20=r20+r28, fr28=r20-r28;;
fr29=r29+r21, fr21=r29-r21;;
fr22=r22+r30, fr30=r22-r30;;
fr31=r31+r23, fr23=r31-r23;;
.align_code 4;
_Stages1and2Loop:
r1:0=q[k0+k6]; q[j2+=4]=yr23:20; fr16=r0+r4, fr24=r0-r4;;
r3:2=q[k2+k6]; q[j3+=4]=xr23:20; fr17=r2+r5, fr25=r2-r5;;
r5:4=q[k1+k6]; q[j14+=4]=yr31:28; fr18=r18+r26, fr26=r18-r26;;
r7:6=q[k3+k6]; q[j15+=4]=xr31:28; fr19=r19+r27, fr27=r19-r27;;
k6=k6+k5 (br); q[j0+=4]=yr19:16; fr0=r0+r2, fr20=r0-r2;;
r9:8=q[k0+k6]; q[j1+=4]=xr19:16; fr2=r1+r3, fr29=r1-r3;;
r11:10=q[k2+k6]; q[j12+=4]=yr27:24; fr4=r4+r6, fr21=r4-r6;;
r13:12=q[k1+k6]; q[j13+=4]=xr27:24; fr5=r5+r7, fr28=r5-r7;;
r15:14=q[k3+k6]; fr18=r8+r10, fr22=r8-r10;;
k6=k6+k5 (br); fr19=r9+r11, fr31=r9-r11;;
fr26=r12+r14, fr23=r12-r14;;
fr27=r13+r15, fr30=r13-r15;;
fr20=r20+r28, fr28=r20-r28;;
fr29=r29+r21, fr21=r29-r21;;
fr22=r22+r30, fr30=r22-r30;;
.align_code 4;
if NLC0E, jump _Stages1and2Loop;
fr31=r31+r23, fr23=r31-r23;;
q[j2+=4]=yr23:20; fr16=r0+r4, fr24=r0-r4;;
q[j3+=4]=xr23:20; fr17=r2+r5, fr25=r2-r5;;
q[j14+=4]=yr31:28; fr18=r18+r26, fr26=r18-r26;;
q[j15+=4]=xr31:28; fr19=r19+r27, fr27=r19-r27;;
q[j0+=4]=yr19:16;;
q[j1+=4]=xr19:16;;
q[j12+=4]=yr27:24;;
q[j13+=4]=xr27:24;;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -