Add real ADSP-2191 assembly examples + open21xx assembler test
This commit is contained in:
181
examples/adsp-2191_complex_rad2_fft/Cfft2_2191.asm
Normal file
181
examples/adsp-2191_complex_rad2_fft/Cfft2_2191.asm
Normal file
@@ -0,0 +1,181 @@
|
||||
/******************************************************************************
|
||||
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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user