182 lines
7.4 KiB
NASM
182 lines
7.4 KiB
NASM
|
|
/******************************************************************************
|
||
|
|
Cfft2_2191.ASM ADSP-2191 Radix-2 DIT Complex FFT
|
||
|
|
|
||
|
|
Performs a radix-2 DIT FFT of length 64 or greater on input data x(n).
|
||
|
|
|
||
|
|
N Real part of normal-ordered complex input stored in DM
|
||
|
|
N Imaginary part of normal-ordered complex input stored in PM
|
||
|
|
N Real part of fft stored in DM
|
||
|
|
N/2 Sin table stored in DM
|
||
|
|
N/2 Cos table stored in PM
|
||
|
|
|
||
|
|
Calling Information:
|
||
|
|
pm(twid_real[N/2]) - sin(2pi*n/N) table in bitreversed order
|
||
|
|
dm(twid_imag[N/2]) - cos(2pi*n/N) table in bitreversed order
|
||
|
|
|
||
|
|
dm(Inputreal[N]) - Real part of complex input array stored in dm
|
||
|
|
pm(Inputimag[N]) - Imaginary part of complex input array stored in pm
|
||
|
|
|
||
|
|
Results:
|
||
|
|
dm(Refft[N]) - Real FFT results ordered sequentially
|
||
|
|
dm(Inputreal[N]) - Imaginary FFT results ordered sequentially
|
||
|
|
|
||
|
|
Benchmarks:
|
||
|
|
FFT Length cycles time (us) 160MHz
|
||
|
|
---------- ------------- ---------------
|
||
|
|
1024 24160 151
|
||
|
|
|
||
|
|
Memory Usage:
|
||
|
|
PM code(24-bit) = 92 words
|
||
|
|
PM data(24-bit) = N + 2 + N/2 words
|
||
|
|
DM data(16-bit) = 2N + 4 + N + 1 words
|
||
|
|
|
||
|
|
******************************************************************************/
|
||
|
|
|
||
|
|
/**********The constants below must be changed for different length FFTs*******
|
||
|
|
|
||
|
|
N = number of points in the FFT, must be a power of 2
|
||
|
|
log2N = log2(N)
|
||
|
|
Mod_Value = 2^(16-LOG2N)
|
||
|
|
Refft_Bitrev = bitrev addr of output real in dm
|
||
|
|
Inputreal_Bitrev = bitrev addr of output imag in dm
|
||
|
|
|
||
|
|
******************************************************************************/
|
||
|
|
|
||
|
|
/* Set Constants for N-point FFT */
|
||
|
|
#define N 1024
|
||
|
|
#define Ndiv2 (N/2)
|
||
|
|
#define log2N 10
|
||
|
|
#define Mod_Value 64
|
||
|
|
#define Refft_Bitrev 0x0001
|
||
|
|
#define Inputreal_Bitrev 0x0009
|
||
|
|
|
||
|
|
|
||
|
|
/* DM data */
|
||
|
|
.section/data data1;
|
||
|
|
.VAR twid_imag [Ndiv2] = "twid_sin.dat";
|
||
|
|
.VAR groups = 1;
|
||
|
|
.VAR node_space = Ndiv2;
|
||
|
|
|
||
|
|
/* DM data */
|
||
|
|
.section/data seg_buf1;
|
||
|
|
.VAR Inputreal [N+2] = "inreal.dat";
|
||
|
|
|
||
|
|
/* DM data */
|
||
|
|
.section/data seg_buf2;
|
||
|
|
.VAR Refft[N+2];
|
||
|
|
|
||
|
|
/* PM data */
|
||
|
|
.section/pm data2;
|
||
|
|
.VAR/init24 twid_real [Ndiv2] = "twid_cos.dat";
|
||
|
|
.VAR Inputimag [N+2] = "inimag.dat";
|
||
|
|
|
||
|
|
/* PM interrupt vector code */
|
||
|
|
.section/pm IVreset;
|
||
|
|
JUMP start; NOP; NOP;
|
||
|
|
|
||
|
|
|
||
|
|
/* Program Code */
|
||
|
|
.section/pm program;
|
||
|
|
start:
|
||
|
|
dmpg2 = page(twid_real); /* Initialize page for PM data */
|
||
|
|
M0 = 0;
|
||
|
|
L0 = length(twid_imag); /* Initialize twid_imag circular buffer */
|
||
|
|
AX1 = twid_imag;
|
||
|
|
REG(b0) = AX1; /* Initialize pointer to twid_imag */
|
||
|
|
M1 = 1;
|
||
|
|
L1 = 0; /* Initialize for modulo addressing */
|
||
|
|
M4 = 0;
|
||
|
|
L4 = length(twid_real); /* Initialize twid_real circular buffer */
|
||
|
|
AX1 = twid_real;
|
||
|
|
REG(b4) = AX1; /* Initialize pointer to twid_real */
|
||
|
|
M5 = 1;
|
||
|
|
L5 = 0; /* Initialize for modulo addressing */
|
||
|
|
M6 = -1;
|
||
|
|
L6 = 0; /* Initialize for modulo addressing */
|
||
|
|
L2 = 0;
|
||
|
|
L3 = 0;
|
||
|
|
L7 = 0;
|
||
|
|
|
||
|
|
CNTR = log2N -1; /* Initialize Stage Counter */
|
||
|
|
DO stage_loop UNTIL CE; /* Compute all stages in FFT */
|
||
|
|
I0 = twid_imag; /* I0 --> (-S) of W0 */
|
||
|
|
I1 = Inputreal; /* I1 --> x1 in 1st group of stage */
|
||
|
|
I2 = Inputreal; /* I2 --> x0 in 1st group of stage */
|
||
|
|
I4 = twid_real; /* I4 --> C of W0 */
|
||
|
|
I5 = Inputimag; /* I5 --> y1 in 1st group of stage */
|
||
|
|
I6 = Inputimag; /* I6 --> y0 in 1st group of stage */
|
||
|
|
SI = DM(groups);
|
||
|
|
CNTR = SI; /* CNTR = # of groups in stage */
|
||
|
|
SR = LSHIFT SI BY 1(LO);
|
||
|
|
DM(groups) = SR0;
|
||
|
|
SI = DM(node_space); /* SI = node_space modifier */
|
||
|
|
M2 =SI;
|
||
|
|
M7 =SI;
|
||
|
|
MODIFY(I1,M2); /* I1 --> x1 in 1st group of stage */
|
||
|
|
MODIFY(I5,M7); /* I5 --> y1 in 1st group of stage */
|
||
|
|
DO group_loop UNTIL CE;
|
||
|
|
MY0 = PM(I4,M5), MX0 = DM(I1,M0); /* MY0=C, MX0=x1 */
|
||
|
|
MR = MX0*MY0(SS), MX1 = PM(I5,M4); /* MR=C*x1,MX1=y1 */
|
||
|
|
MY1 = DM(I0,M1); /* MY1 = (-S) */
|
||
|
|
CNTR = SI; /* CNTR = butterfly counter */
|
||
|
|
DO bfly_loop UNTIL CE;
|
||
|
|
MR = MR-MX1*MY1(RND), AY0 = DM(I2,M0); /* MR=x1*C-y1*-S, AY0=x0 */
|
||
|
|
AR = MR1+AY0, AX1 = PM(I5,M5); /* AR=x0'=x0+(x1*C-y1*-S) */
|
||
|
|
DM(I2,M1) = AR, AR = AY0-MR1; /* DM=x0', AR=x1'=x0-(x1*C-y1*(-S)) */
|
||
|
|
MR = MX0*MY1(SS), DM(I1,M1) = AR; /* MR=x1*(-S), DM=x1' */
|
||
|
|
MR = MR+MX1*MY0(RND), AY1 = PM(I6,M4), MX0 = DM(I1,M0); /*MR=x1*(-S)+y1*C, AY1=y0, MX0=next x1*/
|
||
|
|
AR = MR1+AY1, MX1 = PM(I5,M6); /* AR=y0'=y0+(y1*C+x1*(-S)), MX1= next y1 */
|
||
|
|
PM(I6,M5) = AR, AR = AY1-MR1; /* PM=y0', AR=y1'=y0-(y1*C+x1*(-S)) */
|
||
|
|
bfly_loop:
|
||
|
|
MR = MX0*MY0(SS), PM(I5,M5) = AR; /* PM=y1' */
|
||
|
|
MY0 = PM(I5,M7), MX0 = DM(I1,M2);
|
||
|
|
group_loop:
|
||
|
|
MY0=PM(I6,M7), MX0=DM(I2,M2);
|
||
|
|
SR=ASHIFT SI BY -1 (LO);
|
||
|
|
stage_loop:
|
||
|
|
DM(node_space)=SR0;
|
||
|
|
|
||
|
|
I0 = twid_imag; /* I0 --> (-S) */
|
||
|
|
I1 = Inputreal; /* I1 --> x1 */
|
||
|
|
I2 = Inputreal; /* I2 --> x0 */
|
||
|
|
M2 = 2;
|
||
|
|
I3 = Refft_Bitrev; /* Refft bitreversed */
|
||
|
|
M3 = Mod_Value; /* Bitreversed modifier */
|
||
|
|
I4 = twid_real; /* I4 --> C */
|
||
|
|
I5 = Inputimag; /* I5 --> y1 */
|
||
|
|
I6 = Inputimag; /* I6 --> y0 */
|
||
|
|
M6 = 2;
|
||
|
|
MODIFY(I1,M1); /* I1 -->x1 */
|
||
|
|
MODIFY(I5,M5); /* I5 -->y1 */
|
||
|
|
MY0 = PM(I4,M5), MX0 = DM(I1,M2); /* MY0=C, MX0=x1 */
|
||
|
|
MR = MX0*MY0(SS), MX1 = PM(I5,M6); /* MR = C*x1, MX1 = y1 */
|
||
|
|
MY1 = DM(I0,M1); /* MY1 = (-S) */
|
||
|
|
CNTR = Ndiv2;
|
||
|
|
DO last_loop UNTIL CE;
|
||
|
|
MR = MR-MX1*MY1(RND), AY0 = DM(I2,M2); /* MR=x1*C-y1*(-S), AY0=x0 */
|
||
|
|
AR = MR1+AY0, AY1 = PM(I6,M4); /* AR=x0'=x0+(x1*C-y1*(-S)), AY1=y0 */
|
||
|
|
ENA BIT_REV;
|
||
|
|
DM(I3,M3) = AR, AR = AY0-MR1; /* Read real data */
|
||
|
|
MR = MX0*MY1(SS), DM(I3,M3) = AR; /* Place in sequential order(using bit-reversal) */
|
||
|
|
DIS BIT_REV;
|
||
|
|
MR = MR+MX1*MY0(RND), MY0 = PM(I4,M5), MX0 = DM(I1,M2);
|
||
|
|
AR = MR1+AY1, MX1 = PM(I5,M6); /* AR=y0'=y0+(y1*C+x1*(-S)), MX1= next y1 */
|
||
|
|
PM(I6,M5) = AR, AR = AY1-MR1; /* PM=y0', AR=y1'=y0-(y1*C+x1*(-S)) */
|
||
|
|
MY1 = DM(I0,M1); /* MY1 = (-S) */
|
||
|
|
last_loop:
|
||
|
|
MR = MX0*MY0(SS), PM(I6,M5) = AR; /*PM=y1' */
|
||
|
|
|
||
|
|
I3 = Inputreal_Bitrev;
|
||
|
|
M3 = Mod_Value; /* Bitreversed modifier */
|
||
|
|
I5 = Inputimag;
|
||
|
|
ENA BIT_REV;
|
||
|
|
CNTR = N;
|
||
|
|
DO bit_rev_imag UNTIL CE;
|
||
|
|
AX0 = PM(I5,M5); /* Read imaginary data */
|
||
|
|
bit_rev_imag: DM(I3,M3) = AX0; /* Place in sequential order */
|
||
|
|
DIS BIT_REV;
|
||
|
|
|
||
|
|
looping: JUMP looping;
|
||
|
|
|
||
|
|
|