sábado, 4 de abril de 2009

Core FFT: detalles da implementación e primeiras probas


Antes de comezar co deseño queda resolve-la elección do modo de cálculo do Core FFT: aritmética escalada ou sen escalar. Para decidirnos por unha ou por outra debemos olla-las vantaxes e os inconvenientes de cada un dos modos de operación:

· A aritmética sen escalado evita os desbordamentos nos cálculos no Core basándose no aumento do número de bits no peor dos casos: traballando con n bits para as partes real e imaxinaria de x[n] obteremos X[k] sempre correctamente empregando n + 1 + log2(N), o que neste caso, segundo as especificacións, resulta en 28 bits. Polo tanto, logo do producto das partes real e imaxinaria de X[k] por si mesmas e da suma, suporía un resultado |X[k]| de 56 bits, tendo en conta que o resultado do producto é sempre positivo, polo que podemos ignora-lo bit de signo (tanto re{x[n]}, im{x[n]} como re{x[k]} e im{X[k]} veñen expresadas en Ca2). Por último habería que truncar ou redondear adecuadamente cada un dos resultados e satura-la saída de 9 bits antes de introducila na RAM.

Polo que acabamos de ver, a gran vantaxe da aritmética sen escalado é a evitación de desbordamentos nos cálculos de |X[k]|: se se produce nunha mostra k0, o máis probábel é que |X[k0]| non teña nin o máis mínimo parecido co verdadeiro valor do espectro na frecuencia k0. Pero o grandísimo invonveniente é o soberano desperdicio de recursos que supón. Dado que o monitor non ofrece unha gran precisión na representación dos valores de |X[k]|, parece moito máis sensato experimentar co modo de operación basado na aritmética con escalado, que ademais permite un uso eficiente dos multiplicadores, como vamos a ver.


·A aritmética con escalado implica un certo desprazamento binario á dereita dos resultados de cada mariposa durante o cálculo da FFT. O desprazamento é arbitrario, e pode elixirse entre 0, 1, 2, ou 3 bits. Isto supón polo tanto que os valores calculados neste modo de operación non se correspondan con mostras do espectro dun sinal x[n], senón cunha versión escalada das mesmas: 1/s*X[k], onde s é 2^b, se b coincide co número de bits desprazados en total (cada desprazamento binario supón unha división á metade).

A gran ventaxa da aritmética escalada é que, elixindo o factor adecuadamente, pódese evita-lo desbordamento no cálculo da FFT empregando moitos menos recursos. Concretamente, as saídas (partes real e imaxinaria de X[k]) teñen neste caso n bits, se n é o número de bits da entrada. As nosas especificacións establecen entradas x[n] de 18 bits, co que as saídas tamén terán o mesmo ancho. Por outra banda, os multiplicadores adicados das FPGA’s de Xilinx adoitan ser de 18x18 bits, permitindo resultados de 36; afortunadamente, a FPGA Virtex2 Pro dispón exactamente de multiplicadores con estas características, co que os circuitos que elevan ó cadrado ambos datos de saída do Core FFT poden implementarse de forma moi eficiente, aproveitando ó máximo a circuitería específica.

Por outra banda, os grandes inconvenientes da aritmética escalada son, por unha parte, a perda de precisión que se produce nos desprazamentos, e por outra, a búsqueda dun factor de escala 1/s tal que evite desbordamentos nos cálculos e non agrave excesivamente o problema da precisión.

Para tentar resolver esta difícil cuestión votaremos man do contorno Matlab® da compañía The Mathworks, Inc. O script que se amosa a continuación calcula a FFT de 512 puntos dun tono puro, o peor caso en canto a ampritude espectral, xa que a súa transformada de Fourier sería unha delta convolucionada cunha sinc (debido ó enventanado do sinal x[n]). Cabe destacar que se considera o dato de entrada x[n] como un valor enteiro en Ca2, co que pode tomar valores entre -2^17 e 2^17 – 1.



N = 512;

A = 2^17 - 1;

n = 0 : N - 1;

Ts = 1/48000;

w1 = 2*pi*1000;

x = A*cos(w1*n*Ts);

X = fft(x, N);

figure(1);

stem(2*pi/N*n, real(X));

figure(2);

stem(2*pi/N*n, imag(X));

figure(3);

stem(2*pi/N*n, abs(X));



Con isto ollamos que no peor caso a parte imaxinaria tomará valores de 24.3e6, aproximadamente. Polo tanto, a representación de 2^(-n)*24.3e6 en 18 bits en Ca2 é posíbel se n >= 8. Por seguridade, e dado que non sabemos como se realizan os cálculos dentro do Core, poderiamos empregar como factor s o valor 2^(-9).

Para a proba final xeramos o IPCore FFT de Xilinx na ferramenta ISE, e modelamos en VHDL un compoñente que lle introduza os mesmos 512 valores xerados en matlab, cuantificados con 18 bits en Ca2. Co programa Modelsim XE Starter Edition levamos a cabo unha simulación funcional do compoñente e obtemos o seguinte:



Por outra banda, os resultados obtidos en Matlab son:



Disto séguense os seguintes resultados:

· O Core FFT ofrece unha precisión máis ca suficiente para esta aplicación traballando con aritmética escalada (s = 2^9), e evítase o desbordamento para unha entrada sinusoidal.

· Os valores obtidos como resultados son tales que, se se considera que a entrada é un número enteiro I18 (18 bits en Ca2), a saída será I18, é dicir, a posición da coma non varía (nas follas de características de Xilinx isto non está moi claro, pero nas probas comprobamos que é así).

· O tempo de cálculo da FFT é de 92us cun reloxo de 50MHz, moito menos do esperado nun principio.

A introducción do factor de escala 1/s non supón ningún problema no noso caso: a súa corrección pode efectuarse mediante o calibrado adecuado unha vez rematado o deseño.


Con todo o visto ata agora podemos concluir que a mellor idea é o uso de aritmética escalada, coa que obtemos unha precisión suficiente para esta aplicación, e un aforro de recursos moi considerábel e que nos favorece no uso eficiente dos mesmos. O funcionamento do Core FFT está comprobado e esclarecido, co que o deseño segue adiante!



No hay comentarios:

Publicar un comentario