📄 sub_fft.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 + -