Sei sulla pagina 1di 15

FAST FOURIER TRANSFORM

È un esempio di applicazione che possiamo implementare usando Vivado e Zynq.


FFT significa che io voglio calcolare lo spettro di una sequenza e posso usarla per
diverse applicazioni:

Per implementare la FFT devo calcolare funzioni che non sono lineari e sappiamo
che se volessimo usare un processore per fare ciò avremmo dei problemi.
Se progettiamo la FFT usando un acceleratore hardware possiamo progettare la
funzione non lineare a mano.
Conosciamo la trasformata di Fourier di una sequenza:

Abbiamo una funzione continua e per calcolarla dobbiamo calcolare un numero


infinito di somme.
La trasformate discreta DFT è data da:
Abbiamo la somma di un numero finito di valori e siccome non stiamo calcolando
l’intera espressione della trasformata di Fourier, non stiamo calcolando esattamente
la trasformata, stiamo infatti campionando la trasformata di Fourier, ciò stiamo
calcolando il singolo punto dello spettro della funzione (lo spettro di una funzione è
una funzione continua).
Devo calcolare N somme nella DFT e per ciascuna devo moltiplicare ciascun punto
della sequenza per un esponenziale. Siccome la variabile della espressione k può
assumere N diversi valori, perché il periodo è N della funzione exp, allora ho N
possibili uscite della funzione X(k) e ciascuna uscita richiede N somme. Quindi alla
fine abbiamo N^2 somme per calcolare la DFT.
La FFT è un algoritmo veloce per calcolare la DFT, cioè è la stessa formula ma
l’approccio è più veloce. Si riscrive l’espressione della DFT in questo modo:

Abbiamo una prima somma sui valori dispari e poi una sui valori pari della sequenza.
Se guardiamo alla somma sui punti pari vediamo che possiamo riscrivere la somma
in un altro modo:

K è la variabile della funzione che stiamo calcolando; i è un intero.


Il termine exp è in realtà pari a 1, quindi non sto modificando nulla. Possiamo usare
il primo risultato per k<N/2 per calcolare i risultati per k>=N/2.
Infatti se N=8 allora N/2=4: la prima espressione è valida per N=0,1,2,3 e la seconda
per N=4,5,6,7. Però 4-N/2=0 ecc…
Così facendo dimezziamo il numero di somme che dobbiamo fare.
Inoltre guardando alla espressione delle somme dei campioni pari e dispari vediamo
che stiamo implementando due DFT con un ridotto numero di valori: una DFT su N/2
elementi pari e una su N/2 elementi dispari della sequenza.

Stiamo quindi dividendo la DFT di partenza in due DFT più piccole e per ciascuna
possiamo usare un numero minore di somme. Lo sforzo computazionale è log in
base N di N.
Se guardo a X(k) vedo che per un certo k posso calcolare la prima parte e poi usarla
per calcolare il risultato per un altro valore di k
Quali sono le applicazioni del risultato?
Supponiamo di voler creare un processore di voler calcolare la FFT su N=8 elementi
della sequenza che sono i nostri ingressi e supponiamo di voler calcolare 8 ? valori
che sono quelli della DFT.
Posso dividere le operazioni in due FFT più piccole: una sugli elementi pari e una su
quelli dispari.
Calcoliamo la X(2): devo prendere la uscita 2 della prima FFT e la 2 della seconds FFT
per ottenere l’uscita numero 2 della FFT complessive. Devo prima però moltiplicare
l’uscita numero 2 delle FFT sugli elementi dispari per l’esponenziale di -j2pik/N.

per calcolare X(6) posso prendere l’uscita 2 della prima FFT e la 2 della seconda FFT,
però quest’ultima va moltiplicate per un diverso esponenziale per k è cambiato.
Possiamo però vedere che exp( -j2pik/N)=-exp(-j2pi(k-N/2)/N).
Quindi l’implementazione di questo circuito può essere fatta in questo modo:

L’uscita 2 della FFT sui campioni diaspri è ruotata di 2/8 di 2pi e poi posso sommare
A e B per ottenere X(2) e sottrare A e B per calcolare X(6).

Quindi per ottenere le varie uscite devo in ogni caso avere due ingressi, devo
ruotare uno dei due e poi una volta li somma e una volta li sottraggo.
Possiamo usare un unico elemento hardware per lavorare in parallelo:

BUTTERFLY
L’operazione in cui ci sono due ingressi e uno deve essere ruotato di un certo angolo
per ottenere due uscite è detta algoritmo a farfalla.

Questo è proprio quello che volgiamo fare per calcolare due uscite della FFT.
Se voglio accelerare questo circuito usando l’hardware devo progettare il rotatore
devo fare in parallelo due somme. Posso accelerare in hardware tutta la farfalla,
velocizzando il calcolo della FFT.
Siccome stiamo calcolando lo spettro di una funzione x1,x2,y1,y2 sono numeri
complessi, quindi per y1 dobbiamo calcolare in realtà due somme, una per la parte
reale e una per quella immaginaria, lo stesso per y2. Quindi nel complesso ci sono 4
somme e dobbiamo applicare una rotazione a un vettore complesso.
Le uscite della farfalla sono complesse e quindi otteniamo 4 valori di uscita.
Se l’intero blocco lo rappresentiamo come il blocco a destra in cui indichiamo la
frazione di 2pi di cui vogliamo ruotare il secondo ingresso allora possiamo
rappresentare la FFT così:

quali sono gli ingressi di ogni farfalla e gli angoli di rotazione?


le uscite delle due FFT4 sono rappresentate come lista di valori e vogliamo usare 4
farfalle per ottenere gli 8 risultati. La prima farfalla lavora sulle uscite 0 e 1 delle due
FFT4 ecc…
la FFT4 può essere divisa in due FFT2:

Poi usiamo due farfalle per calcolare le 4 uscite della prima FFT4 a partire dalle 4
uscite delle due FFT2. Quindi per ciascun blocco FFT ho bisogno die un numero di
farfalle che è la metà delle uscite della singola FFT che voglio calcolare.
Le due FFT2 posso essere implementate usando due FFT1:
Ma una FFT con un solo campione è il campione stesso quindi posso usare una
farfalla per implementare la FFT2.
Così facendo otteniamo:

Abbiamo un numero di stadi di farfalle che è log in base 2 di N e in ogni stadi usiamo
un numero di farfalle che è il numero uscite che vogliamo ottenere diviso 2.

HW/SF DECOMPOSITION

Se il processore lavorare su una lunga sequenza ci serviranno molte butterfly, ma se


volgiamo lavorare su una piccola seq abbiamo diverse possibilità.
Noi vediamo solo come progettare la farfalla.

Avremo 5 ingressi
Ci serve un ruotatore, cioè vogliamo calcolare il prodotto tra x2, che è un numero
complesso, e un vettore che è il coseno e seno di -2pik/N. quindi devo calcolare il
seno e coseno di questo ritardo di fase e per fare ciò posso usare una ROM, una LUT.
Cioè scegliamo il numero di bit che vogliamo usare per descrivere la fase e quanti bit
usare per il risultato e poi creo la ROM per fare la rotazione.
Il calcolo computazionale da fare è:

useremo full precision per segnali interni e poi limito i bit per le uscite
Quindi nella butterfly dovremmo fare un conto così srutturato:
Quindi siccome l’uscita di una farfalla sarà l’ingresso di un’altra non posso
aumentare il numero di bit e quindi devo eliminare i primi 4 bit. Così facendo stiamo
dicendo che può esserci overflow in alcuni casi. Devo eliminare anche i bit frazionari
perché l’uscita andrà in ingresso a un’altra butterfly che non ha bit frazionari, per cui
sto generando un errore di approssimazione, anche se so che sarà piccolo.
Ogni volta che uso una farfalla aumento il dynamic range di 2 bit perché l’uscita può
essere più grande dell’ingresso. Per la FFT8 con 3 stadi di buttefly sto aumentando il
dynimic range dell’uscita di 3 volte e sto usando 6 bit più dell’ingresso.
Quindi se uso 8 bit per l’ingresso delle butterfly, il primo stadio ha ingressi definiti su
2 bit perché gli altri 6 mi servono per incrementare il dynamic range dell’ingresso.
Riepilogo:
BUTTERFLY HDL
Nel design del prof che 1 butterfly senza parallelismo con ingressi su 8 bit
Il modoc on cui la ip si connette all’amba bus è : 1

Useremo i reg 11-15 per dare 5 ingressi alle butterfly e i reg da 1 a 4 per uscite, il
reg 0 è usato per handshake tra ip e processore
Non posso usare le stesssa interfaccia per inge sucite

Potrebbero piacerti anche