⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ifft.asm

📁 54系列dsp算法程序
💻 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 + -