Files

182 lines
7.4 KiB
NASM
Raw Permalink Normal View History

/******************************************************************************
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;