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

📄 sub_fft.s

📁 此为Microchip的试验程序
💻 S
字号:
;START_HEADER
;
; dsPIC30F6014 Demo Source File
; (c) Copyright 2005 Microchip Technology, All rights reserved
;
; --------------------------------------------------------------------------
; File Revision History:
; --------------------------------------------------------------------------
;
; $Log: sub_fft.s,v $
; Revision 1.1  2006/07/07 15:32:08  c13075
; initial rev
;
; Revision 1.2  2005/04/04 23:38:56  VasukiH
; Updated comments in header
;
; Revision 1.1.1.1  2003/08/23 00:38:33  VasukiH
; First import of demo source into CVS Repository
;
;
;
; --------------------------------------------------------------------------
;
; Software and Development Tools Info:
; --------------------------------------------------------------------------
; Tool                          Version
; --------------------------------------------------------------------------
; MPLAB IDE                     7.0
; MPLAB C30 Toolsuite           1.30
; dsPICDEM(TM) Processor Board  1.10
; --------------------------------------------------------------------------
;
; File Notes:
; 1. This file contains the actual in-place FFT implementation.
;    The approach used is a decimation in time approach.
;
;END_HEADER

        .section .text
        .global _sub_fft
_sub_fft:
        push.d  w4
        push.d  w6
        push.d  w8
        push.d  w10
        push.d  w12
        push    MODCON
        nop
        push    XBREV
        nop


        add     w0,w2,w4
        add     w4,w2,w4
        dec2    w4,w4                   ; w4 now points to last real element in real (non-interleaved) array
        add     w4,w2,w5
        add     w5,w2,w5                ; w5 now points to last imaginary element in complex (interleaved) array

        dec     w2,w2                   ; Adjust loop count

        inc w3, w3

        do      w2,loopnd

        mov     [w4--],w6
        asr     w6,w3,w6                ; Scale each data sample by '2^N' to prevent overflow

        clr     [w5--]                  ; Imaginary element cleared in interleaved array
                                        ; w5 now points to real element
loopnd: mov     w6,[w5--]               ; Real element copied over to its proper position in interleaved array
                                        ; w4 now points to previous real element in non-interleaved array
                                        ; w5 now points to previous imaginary element in interleaved array

        dec     w3, w3

        inc    w2,w2                    ; Restore w2 value

        ; Now the array contains the Real input data and the 'zero' Imaginary data, interleaved.



        ; Shuffle the elements of input data via bit-reversed addressing.
        mov     w0,w9                   ; Initialize sequential address pointer w9
        mov     w0,w8                   ; Initialize bit-reversed address pointer w8

        ; Set up bit reversed addressing with W8 as pointer
        mov     #0x08ff,w4
        mov     w4,MODCON

        ; and enable bit reversed addressing with a bit-reversed modifier of 256 words
        mov     #0x8000,w4
        ior     w4,w2,w4
        mov     w4,XBREV

        dec     w2,w2                   ; Adjust loop count

        ;; In-place-implementation - Reorder Data
        do      w2,router
        cp      w9,w8                   ; Check if bit-reversed address is greater than sequential address

        bra     ge,next                 ; If not, move on to next element

        ;; If yes, swap the two elements pointed to by the sequential and bit-reversed pointers.
        mov     [w9],w4                 ; Load R->w4
        mov     [w8],[w9]               ; Move Real
        mov     w4,[w8]                 ; Store w4->[w8]

next:   add     #0x04,w9                ; Increment the sequential address.
router: mov     [w8],[w8++]             ; Modify the bit-reversed pointer.

        inc     w2,w2                   ; Restore w2 value

        clr     XBREV                   ; Bit-reversed addressing is now disabled.

        ;; -------------------- FFT Stages --------------------

        ; w2 initially equal to FFT size
        ; w3 keeps count of the stages.

        mov     #0x0004,w12    ; Number of 'values' (real AND imaginary) in each block in current stage
        mov     #0x0001,w5     ; Number of butterflies in each block in current stage (init. to 1 for first stage)
        sl      w2,w11         ; w11 is the stride size of the twiddle factor pointer in bytes
                               ; (init. to 2*FFT_SIZE bytes for first stage)


        asr     w2,w2          ; w2 is the number of blocks (init. to FFT_SIZE/2 for first stage)

        ; Now loop over the remaining stages, beginning with the third stage.

        ;; -------------------- Beginning of Stage Loop --------------------
outer:  mov     w0,w8                   ; Data pointer re-initialized.

        dec     w2,w2                   ; Adjust middle do loop count
        dec     w5,w5                   ; Adjust inner do loop count



        do      w2,middle               ; Loop over blocks in a stage.

        mov     w1,w10                  ; Initialize pointer to twiddle factors.

        do      w5,inner                ; Loop over butterflies in a block.

        ; Doing the actual butterfly operation here...
        add     w12,w8,w9               ; w8 points to ar, w9 points to br.

        clr     B,[w9]+=2,w6,[w10],w7   ; br and wr prefetched. w9 now points to bi and w10 to wr.

        mpy     w6*w7,A,[w9],w6,[w10]+=2,w7    ; br*wr, bi & wr prefetched, w9 and w10 now point to bi and wi.
        mac     w6*w7,B,[w9]-=2,w6,[w10],w7    ; bi*wr, bi and wi prefetched, w9 and w10 now point to br & wi.

        msc     w6*w7,A,[w9],w6,[w10]-=2,w7    ; br*wr - bi*wi, br & wi prefetched, w9 and w10 now point to br & wr.
        mac     w6*w7,B,[w9],w6,[w10],w7,w13   ; bi*wr + br*wi, prefetch redundant.
                                        ; tempr stored (tempr = br*wr - bi*wi) in w13.
        sac.r   B,#0,w4                 ; tempi stored (tempi = bi*wr + br*wi) in w4.

        subr    w13,[w8++],[w9++]       ; New Br = ar - tempr, w8 and w9 now point to ai and bi.
        subr    w4,[w8--],[w9++]        ; New Bi = ai - tempi, w8 now points to ar, and w9 to br of next butterfly.

        add     w13,[w8],[w8++]         ; New Ar = ar + tempr, w8 now points to ai.
        add     w4,[w8],[w8++]          ; New Ai = ai + tempi, w8 now points to ar of next butterfly.

inner:  add     w11,w10,w10             ; Increment twiddle factor pointer by appropriate amount.
        ; Now, w8/w9 points to ar/br of next butterfly.

middle: add     w12,w8,w8               ; Point to first ar of NEXT block.

        inc     w2,w2                   ; Re-adjust the do loop counts to get an even count.
        inc     w5,w5

        asr     w2,w2                   ; Number of blocks is halved in next stage.
        asr     w11,w11                 ; Twiddle factor stride size is halved for next stage.
        sl      w12,w12                 ; Block size doubled in next stage.
        sl      w5,w5                   ; Number of butterflies per block also doubled.
        dec     w3,w3                   ; Stage number decreased.
        bra     NZ,outer
        ;; -------------------- End of Stage Loop --------------------


        pop     XBREV
        nop
        pop     MODCON
        nop

        pop.d   w12
        pop.d   w10
        pop.d   w8
        pop.d   w6
        pop.d   w4

        return


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -