📄 fft.asm
字号:
.title "fft.asm"
.mmregs
.include "coeff.inc"
.include "in.inc"
.def start
sine: .usect "sine",512
cosine: .usect "cosine",512
fft_data: .usect "fft_data",1024
*d_input: .usect "d_input",1024 ;输入数据的起始地址
fft_out: .usect "fft_out",512 ;输出数据的起始地址
STACK .usect "STACK",10
K_DATA_IDX_1 .set 2
K_DATA_IDX_2 .set 4
K_DATA_IDX_3 .set 8
K_TWID_TBL_SIZE .set 512
K_TWID_IDX_3 .set 128
K_FLY_COUNT_3 .set 4
K_FFT_SIZE .set 64 ;N=64,复数点数
K_LOGN .set 6 ;LOGN(N)=LOG(64)=6,蝶形级数
PA0 .set 0
*PA1 .set 1
.bss d_twid_idx,1
.bss d_data_idx,1
.bss d_grps_cnt,1
.sect "fft_prg"
********************位码倒置程序**************************
.asg AR2,REORDERED ;以位翻转顺序指向已处理的数据
.asg AR3,ORIGINAL_INPUT ;指向原始数据
.asg AR7,DATA_PROC_BUF ;数据的起始地址
start: SSBX FRCT ;允许小数乘
STM #STACK+10,SP
* STM #d_input,AR1 ;从PA1口输入2N个数据
* RPT #2*K_FFT_SIZE-1
* PORTR PA1,*AR1+
STM #sine,AR1 ;将正弦系数从程序存储器传送到数据存储器
RPT #511
MVPD #sine1,*AR1+
STM #cosine,AR1 ;将余弦系数从程序存储器传送到数据存储器
RPT #511
MVPD cosine1,*AR1+
STM #d_input,ORIGINAL_INPUT ;AR3指向第一个输入数据
STM #fft_data,DATA_PROC_BUF ;AR7中存储数据的起始地址
MVMM DATA_PROC_BUF,REORDERED ;AR2指向第一个被处理的数据
STM #K_FFT_SIZE-1,BRC ;块重复N=64次
RPTBD bit_rev_end-1 ;重复结束位置
STM #K_FFT_SIZE,AR0
;AR0赋值为循环缓冲器大小的一半
MVDD *ORIGINAL_INPUT+,*REORDERED+
MVDD *ORIGINAL_INPUT-,*REORDERED+
MAR *ORIGINAL_INPUT+0B ;位翻转寻址
bit_rev_end:
*********************FFT CODE*********************************
.asg AR1,GROUP_COUNTER ;组计数器
.asg AR2,PX ;第一级和第二级蝶形运算中
;指向第一个蝶形的输入数据PR和PI
.asg AR3,QX ;第一级和第二级蝶形运算中
;指向第二个蝶形的输入数据QR和QI
.asg AR4,WR ;剩余级蝶形运算中指向(COSINE表)
.asg AR5,WI ;剩余级蝶形运算中指向(SINE表)
.asg AR6,BUTTERFLY_COUNTER ;蝶形运算次数计数器
.asg AR7,STAGE_COUNTER ;蝶形级数计数器
*******************第一级蝶形运算stage1************************
STM #0,BK ;循环缓冲器大小BK=0
LD #-1,ASM ;每一级的输出都除以2
STM #fft_data,PX ;AR2指向第一个蝶形运算输入实部PX
STM #fft_data+K_DATA_IDX_1,QX ;AR3指向第二个蝶形运算输入实部QX
STM K_FFT_SIZE/2-1,BRC
LD *PX,16,A ;A:=PX
RPTBD stage1end-1 ;块重复
STM #K_DATA_IDX_1+1,AR0
SUB *QX,16,A,B ;B:=PX-QX
ADD *QX,16,A ;A:=PX+QX
STH A,ASM,*PX+ ;PX':=(PX+QX)/2
ST B,*QX+ ;QX':=(PX-QX)/2
||LD *PX,A ;A:=WR
SUB *QX,16,A,B ;B:=WR-WI
ADD *QX,16,A ;A:=WR+WI
STH A,ASM,*PX+0% ;WR'=(WR+WI)/2
ST B,*QX+0% ;WI'=(WR-WI)/2
||LD *PX,A ;A:=WR
stage1end:
******************第二级蝶形运算stage2***************************
STM #fft_data,PX ;PX -> PR
STM #fft_data+K_DATA_IDX_2,QX ;QX -> QR
STM #K_FFT_SIZE/4-1,BRC
LD *PX,16,A ;A := PR
RPTBD stage2end-1
STM #K_DATA_IDX_2+1,AR0
;1st butterfly
SUB *QX,16,A,B ;B := PR-QR
ADD *QX,16,A ;A := PR+QR
STH A,ASM,*PX+ ;PR':= (PR+QR)/2
ST B,*QX+ ;QR':= (PR-QR)/2
||LD *PX,A ;A := PI
SUB *QX,16,A,B ;B := PI-QI
ADD *QX,16,A ;A := PI+QI
STH A,ASM,*PX+ ;PI':= (PI+QI)/2
STH B,ASM,*QX+ ;QI':= (PI-QI)/2
;2nd butterfly
MAR *QX+
ADD *PX,*QX,A ;A := PR+QI
SUB *PX,*QX-,B ;B := PR-QI
STH A,ASM,*PX+ ;PR':= (PR+QI)/2
SUB *PX,*QX,A ;A := PI-QR
ST B,*QX ;QR':= (PR-QI)/2
||LD *QX+,B ;B := QR
ST A,*PX ;PI':= (PI-QR)/2
||ADD *PX+0%,A ;A := PI+QR
ST A,*QX+0% ;QI':= (PI+QR)/2
||LD *PX,A ;A := PR
stage2end:
********************第三级至最后一级蝶形运算************************
STM #K_TWID_TBL_SIZE,BK ;BK=twiddle table size always
ST #K_TWID_IDX_3,d_twid_idx ;init index of twiddle table
STM #K_TWID_IDX_3,AR0 ;AR0 = index of twiddle table
STM #cosine,WR ;init WR pointe
STM #sine,WI ;init WI pointer
STM #K_LOGN-2-1,STAGE_COUNTER ;init stage counter
ST #K_FFT_SIZE/8-1,d_grps_cnt ;init group counter
STM #K_FLY_COUNT_3-1,BUTTERFLY_COUNTER ;init butterfly counter
ST #K_DATA_IDX_3,d_data_idx ;init index for input data
stage:
STM #fft_data,PX ;PX->PR
LD d_data_idx,A
ADD *(PX),A
STLM A,QX ;QX -> QR
MVDK d_grps_cnt,GROUP_COUNTER ;AR1 contains group countergroup
group:
MVMD BUTTERFLY_COUNTER,BRC ;The number of butterflies in each
RPTBD butterflyend-1
LD *WR,T
MPY *QX+,A ;A := QR*WR || QX?QI
MAC *WI+0%,*QX-,A ;A := QR*WR+QI*WI
* LD A,15,A
ADD *PX,16,A,B ;B:=(QR*WR+QI*WI)+PR
ST B,*PX ;PR':=((QR*WR+QI*WI)+PR)/2
||SUB *PX+,B ;B := PR-(QR*WR+QI*WI)
ST B,*QX ;QR':= (PR-(QR*WR+QI*WI))/2
||MPY *QX+,A ;A := QR*WI [T=WI]
MAS *QX,*WR+0%,A ;A := QR*WI-QI*WR
* LD A,15,A
ADD *PX,16,A,B ;B := (QR*WI-QI*WR)+PI
ST B,*QX+ ;QI':=((QR*WI-QI*WR)+PI)/2
||SUB *PX,B ;B := PI-(QR*WI-QI*WR)
LD *WR,T ;T := WR
ST B,*PX+ ;PI':= (PI-(QR*WI-QI*WR))/2
||MPY *QX+,A ;A := QR*WR || QX?QI
butterflyend:
;Updata pointers for next group
PSHM AR0 ;preserve AR0
MVDK d_data_idx,AR0
MAR *PX+0 ;increment PX for next group
MAR *QX+0 ;increment QX for next group
BANZD group,*GROUP_COUNTER-
POPM AR0 ;restore AR0
MAR *QX-
;Updata counters and indices for next stage
LD d_data_idx,A
SUB #1,A,B ;B = A-1
STLM B,BUTTERFLY_COUNTER ;BUTTERFLY_COUNTER = #flies-1
STL A,1,d_data_idx ;double the index of data
LD d_grps_cnt,A
STL A,ASM,d_grps_cnt ;1/2 the offset to next group
LD d_twid_idx,A
STL A,ASM,d_twid_idx ;1/2 the index of twiddle table
BANZD stage,*STAGE_COUNTER-
MVDK d_twid_idx,AR0 ;AR0 = index of twiddle table
fft_end:
***********************计算功率谱***************************************
STM #fft_data,AR2
; STM #fft_data,AR3
STM #fft_out,AR4
STM #K_FFT_SIZE*2-1,BRC
RPTB power_end-1
SQUR *AR2+,A ;A := AR^2
SQURA *AR2+,A ;A := AR^2 + AI^2
STH A,*AR4+
power_end:
STM #fft_out,AR4
RPT #K_FFT_SIZE-1
PORTW *AR4+,PA0
NOP
NOP
here: B here
.end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -