📄 ifft.asm
字号:
*********************************************************************************
* (C) COPYRIGHT TEXAS INSTRUMENTS, INC. 1996 *
*********************************************************************************
* *
* FILE NAME: IFFT.asm *
* *
* AUTHORS: Simon Lau and Nathan Baltz *
* *
* DESCRIPTION: *
* - TMS320C54x N-point Complex IFFT *
* Radix 2, in-place DIT algorithm *
* - For various input sizes (16 - 512), simply modify N and LOGN. *
* - Input data is assumed to be in Q0.15 format, stored in natural order, *
* interleaved real/complex, in a data file named "Indata1" *
* - Bit-reversal of input data is done automatically before performing the IFFT*
* - Computation is done in place, so the outputs come in natural order, *
* interleaved real/complex. *
* - Twiddle factors are stored in normal order in two separate tables, *
* one for sine values and the other for cosine. *
* - Total size of twiddle tables is 1024 bytes for IFFT size up to 1024 points.*
* Same twiddle tables are used for IFFT size from 16 to 512. *
* - For additional information about the implementation of this code refer to *
* the readme.txt file. *
* *
* DATE: Summer 1996 *
* *
*********************************************************************************
.mmregs
.global reset,begin,stage,group,btflyend
N .set 16 ; number of complex points
LOGN .set 4 ; number of stages (=logN/log2)
; Copy input data and twiddle tables from files
.data
DATA .space 2*N*16 ; start addr. of complex output data
INPUT .copy indata1 ; start addr. of complex input data
.sect "twiddle1"
TWI1 .copy twiddle1 ; sine table
.sect "twiddle2"
TWI2 .copy twiddle2 ; cosine table
; Define variables for indexing input data and twiddle tables
.def sav_grp
sav_grp .usect "tempv",3 ; saves (# groups in current stage)-1
sav_sin .set sav_grp+1 ; saves index of twiddle tables
sav_idx .set sav_grp+2 ; saves index of input data table
; Set up stack
BOS .usect "stack",0Fh
TOS .usect "stack",1
; Power up initialization ------------------------------------------------------
.sect "vectors"
reset:
BD begin
STM #TOS,SP
.text
begin:
LD #0,DP
SSBX FRCT ; fractional mode is on
;-------------------------------------------------------------------------------
; P H A S E O N E Bit-Reversal of Input Data
;
; REGISTER USAGE: AR0 index for bit-reversed addressing
; AR2 pointer to R, I (processed data, in bit-reversed order)
; AR3 pointer to XR, XI (original input data)
; AR7 start addr. of data
;-------------------------------------------------------------------------------
STM #INPUT,AR3 ; AR3 points to 1st input XR[0]
STM #DATA,AR7 ; store start addr. of data in AR7
MVMM AR7,AR2 ; AR2 points to 1st processed data R[0]
STM #N-1,BRC
RPTBD p1end-1
STM #N,AR0 ; AR0 := 1/2 the size of circular buffer
MVDD *AR3+,*AR2+
MVDD *AR3-,*AR2+
MAR *AR3+0B ; bitrev(k)
p1end:
;-------------------------------------------------------------------------------
; P H A S E T W O (LogN)-Stage Complex IFFT
;
; Outputs are divided by 2 at each stage to prevent overflow
;
; REGISTER USAGE: AR0 offset to next butterfly
; (stages 1 & 2) AR2 pointer to PR, PI (1st butterfly input data)
; AR3 pointer to QR, QI (2nd butterfly input data)
; AR7 start addr. of data
;
; REGISTER USAGE: AR0 index of twiddle tables
; (remainder) AR1 group counter
; AR2 pointer to PR, PI (1st butterfly input data)
; AR3 pointer to QR, QI (2nd butterfly input data)
; AR4 pointer to WR (cosine)
; AR5 pointer to WI (sine)
; AR6 butterfly counter
; AR7 stage counter
;-------------------------------------------------------------------------------
; Stage 1 ----------------------------------------------------------------------
STM #0,BK ; circular buffer size BK=0
LD #-1,ASM ; outputs divided by 2 at every stage
MVMM AR7,AR2 ; AR2 points to PR
STM #DATA+2,AR3 ; AR3 points to QR
STM #N/2-1,BRC
LD *AR2,16,A ; A := PR
RPTBD s1end-1
STM #3,AR0
SUB *AR3,16,A,B ; B := PR-QR
ADD *AR3,16,A ; A := PR+QR
STH A,ASM,*AR2+ ; PR':= (PR+QR)/2
ST B,*AR3+ ; QR':= (PR-QR)/2
||LD *AR2,A ; A := PI
SUB *AR3,16,A,B ; B := PI-QI
ADD *AR3,16,A ; A := PI+QI
STH A,ASM,*AR2+0 ; PI':= (PI+QI)/2
ST B,*AR3+0% ; QI':= (PI-QI)/2
||LD *AR2,A ; A := PR
s1end:
; Stage 2 ----------------------------------------------------------------------
MVMM AR7,AR2 ; AR2 points to PR
STM #DATA+4,AR3 ; AR3 points to QR
STM #N/4-1,BRC
LD *AR2,16,A ; A := PR
RPTBD s2end-1
STM #5,AR0
; 1st butterfly
SUB *AR3,16,A,B ; B := PR-QR
ADD *AR3,16,A ; A := PR+QR
STH A,ASM,*AR2+ ; PR':= (PR+QR)/2
ST B,*AR3+ ; QR':= (PR-QR)/2
||LD *AR2,A ; A := PI
SUB *AR3,16,A,B ; B := PI-QI
ADD *AR3,16,A ; A := PI+QI
STH A,ASM,*AR2+ ; PI':= (PI+QI)/2
STH B,ASM,*AR3+ ; QI':= (PI-QI)/2
; 2nd butterfly
MAR *AR3+
SUB *AR2,*AR3,A ; A := PR-QI
ADD *AR2,*AR3-,B ; B := PR+QI
STH A,ASM,*AR2+ ; PR':= (PR-QI)/2
ADD *AR2,*AR3,A ; A := PI+QR
ST B,*AR3 ; QR':= (PR+QI)/2
||LD *AR3+,B ; B := QR
ST A,*AR2 ; PI':= (PI+QR)/2
||SUB *AR2+0%,A ; A := PI-QR
ST A,*AR3+0% ; QI':= (PI-QR)/2
||LD *AR2,A ; A := PR
s2end:
; Remaining stages -------------------------------------------------------------
STM #512,BK ; circular buffer size BK=512 always
ST #128,@sav_sin ; init index of twiddle table, 128 for
; 3rd stage, ... 4 for 8th stage, ...
STM #128,AR0 ; index of twiddle table for 3rd stage
STM #TWI2,AR4 ; AR4 points to WR
STM #TWI1,AR5 ; AR5 points to WI
STM #-3+LOGN,AR7 ; init stage counter
ST #-1+N/8,@sav_grp ; init group counter
STM #3,AR6 ; init butterfly counter = #flies - 1
ST #8,@sav_idx ; init index for input data
stage:
STM #DATA,AR2 ; AR2->PR (AR2 points to PR)
LD @sav_idx, A
ADD *(AR2),A
STLM A,AR3 ; AR3->QR (AR3 points to QR)
MVDK @sav_grp,AR1 ; AR1 contains group counter
group:
MVMD AR6,BRC ; # of butterflies in each group
RPTBD bend-1
LD *AR4,T ; T := WR
MPY *AR3+,A ; A := QR*WR || AR3->QI
MASR *AR5+0%,*AR3-,A ; A := QR*WR-QI*WI || AR3->QR
ADD *AR2,16,A,B ; B := (QR*WR-QI*WI)+PR
ST B,*AR2 ; PR':=((QR*WR-QI*WI)+PR)/2
||SUB *AR2+,B ; B := PR-(QR*WR-QI*WI) || AR2->PI
ST B,*AR3 ; QR':= (PR-(QR*WR-QI*WI))/2
||MPY *AR3+,A ; A := QR*WI [T=WI] || AR3->QI
MACR *AR3,*AR4+0%,A ; A := QR*WI+QI*WR
ADD *AR2,16,A,B ; B := (QR*WI+QI*WR)+PI
ST B,*AR2 ; PI':=((QR*WI+QI*WR)+PI)/2
||SUB *AR2+,B ; B := PI-(QR*WI+QI*WR) || AR2->PR
ST B,*AR3+ ; QI':= (PI-(QR*WI+QI*WR))/2 || AR3->QR
||LD *AR4,T ; T := WR
MPY *AR3+,A ; A := QR*WR || AR3->QI
bend:
; Update pointers for next group
PSHM AR0 ; preserve AR0
MVDK @sav_idx,AR0
MAR *AR2+0 ; increment P pointer for next group
MAR *AR3+0 ; increment Q pointer for next group
BANZD group,*AR1-
POPM AR0 ; restore AR0
MAR *AR3-
; Update counters and indices for next stage
LD @sav_idx,A
SUB #1,A,B ; B = A-1
STLM B,AR6 ; update butterfly counter = #flies-1
STL A,1,@sav_idx ; double the index of data table
LD @sav_grp,A
STL A,ASM,@sav_grp ; half the offset to next group
LD @sav_sin,A
STL A,ASM,@sav_sin ; half the index of twiddle table
BANZD stage,*AR7-
MVDK @sav_sin,AR0 ; AR0 contains index of twiddle table
self B self
.end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -