;***************************************************************************************************** ; fft.asm ; Algorithme de calcul de la transformee de Fourier rapide TFR ; - sur place (les sorties de la FFT écrasent les échantillons du signal) ; - décimation temporelle ; ; Benoit Decoux, TP DSP, EFREI 2002-2003 ; (à partir du programme fftc563.asm de Motorola et du travail de projet de ; fin d'études de MM. Barbiero et Valette, promotion 2002). ;***************************************************************************************************** fft macro points,data,coef ; macro fft ;initialisation des registres de décalage (papillons, groupes et coefficients W(n,k) move #points/2,n0 ; n0 = nombre de papillons par groupe (valeur initiale : 'points'/2) move #1,n2 ; n2 = nombre de groupes dans la passe (valeur initiale : 1) move #points/4,n6 ; n6 pour acceder aux valeurs sinus et cosinus des W(n,k) ; (la moitié de la taille du tableau) ;mode d'adressage move #-1,m0 ; m0 = $FFFF, adressage lineaire move m0,m1 ; idem pour m1 move m0,m4 ; idem pour m4 move m0,m5 ; idem pour m5 move #0,m6 ; adressage en binaire inverse pour r6 (acces aux W(n,k)) do #@cvi(@log(points)/@log(2)+0.5),_fin_pass ; boucles sur les passes (N=2^P itérations) ;initialisation des ptr de calcul et enreg move #data,r0 ; r0 contient l'adresse de base des échantillons "data" move r0,r4 ; idem pour r4 move #coef,r6 ; r6 pointe sur l'adresse de base de "coef" lua (r0)+n0,r1 ; r1 contient l'adresse du N/2e échantillon ;initialisation des registres de décalage move n0,n1 ; registre de decalage n1 <- nb papillon par groupe move n0,n4 ; idem n4 move n0,n5 ; idem n5 nop lua (r1)-,r5 ; r5=r1-1 (adresse du N/2-1e échantillon) do n2,_fin_grpe ; boucle sur les groupes (n2 iterations) ;init des calculs intermédiaires move x:(r1),x1 y:(r6),y0 ; x1 <- Re[B], y0 <- sinus (car r6=coef) move x:(r5),a y:(r0),b ; A <- Re[B], B <- Im[A] move x:(r6)+n6,x0 ; x0 <- cosinus (n6=points/4) et r6 remis a jour pour prochaine iteration do n0,_fin_papi ; boucle sur les papillons (n0 iterations) mac -x1,y0,b y:(r1)+,y1 ; B <- (B=Im[A])-Re[B]*sinus (calcul intermédiaire) ; y1 <- Im[B] et r1++ macr x0,y1,b a,x:(r5)+ y:(r0),a ; B <- (B=Im[A]-Re[B]*sinus)+Im[B]*cosinus=Im[A'] ; X <- (A=Re[B]) et r5++ (sauvegarde en mémoire X) ; A <- Im[A] subl b,a x:(r0),b b,y:(r4) ; A <- (Im[B']=2*Im[A]-Im[A']) ; B <- Re[A] ; Y <- Im[A'] (sauvegarde en mémoire Y) mac x1,x0,b x:(r1),x1 ; B <- (B=Re[A])+Re[B]*cosinus (calcul intermédiare) ; x1 <- Re[B] macr y1,y0,b x:(r0)+,a a,y:(r5) ; B <- Re[A']=(B=Re[A]+Re[B]*cosinus)+Im[B]*sinus) ; A <- Im[A] et r0++ ; Y <- Im[B'] (sauvegarde en mémoire Y) subl b,a b,x:(r4)+ y:(r0),b ; A <- (2*Re[A]-Re[A']=Re[B']) ; X <- Re[A'] et r4++ (sauvegarde en mémoire X) ; B <- Im[A] _fin_papi ;mises à jour pour papillons move x:(r0)+n0,x1 y:(r4)+n4,y1 ; x1 <- Re[B] et r0=r0+n0 ; r4=r4+n4 move a,x:(r5)+n5 y:(r1)+n1,y1 ; X <- (A=Re[B']) et r5=r5+n5 ; y1 <- Im[B] et r1=r1+n1 _fin_grpe move n0,b1 ; b1 <- nombre de papillons par groupe lsr b ; division du nombre de papillons/groupes par 2 move n2,a1 ; a1 <- nombre de groupes par passe lsl a ; multiplication du nombre de goupes/passe par 2 move b1,n0 ; mise à jour de n0 avec son nouveau contenu move a1,n2 ; idem pour n2 _fin_pass endm ; fin macro