domingo, 24 de mayo de 2009

Bloque de control RGB da interfaz VGA

O bloque de control de RGB consta de tres compoñenetes distintas (aínda que moi parecidas), pero teñen unha parte en común. Sen embargo tamén será necesario explicar cada unha por separado:

a) Común ás compoñentes RGB.

Cada unha das compoñentes é a encargada de mandar os píxeles de cor vermella, verde e azul ó conversor D/A. Así temos o dato a representar como entrada e un sinal de 8 bits á saída de cada un dos tres bloques, que será a entrada do conversor (se os 8 bits están a 0, non terá compoñente da core en cuestión, e a medida que aumenta, aumentará a aportación desa cor).

Deste xeito, a parte dos correspondetes marxes nos que o pixel está desactivo (o pórtico frontal ou esquerdo, o traseiro ou dereito e o retorno) tanto para os píxeles horizontais como para os verticais; incluiremos un borde superior e outro inferior (que decidimos que fose de 5 píxeles cada un) e un dereito e outro esquerdo (de 57 píxeles cada un). Así nos nosos bordes, as compoñentes das cores serán nulas.

Destinaremos 460 píxeles para representar os datos (que é o máximo valor que pode tomar a FFT) en vertical e 512 para a representación horizontal (os píxeles correspondentes ós datos, serán descritas con detalle en cada un dos bloques). Pero a parte dos datos irá bordeada pola esquerda e por abaixo por uns eixos (coa mesma lonxitude de píxeles) que terán 4 píxeles de ancho cada un.

Ademáis, dos eixos decidimos incluir letras para indicar a qué se corresponde cada un dos eixos. Así, para o eixo de ordenadas , onde se representa o módulo ó cadrado da FFT, deixamos 13 píxeles dende o eixo cara a esquerda. Pois, en horizonta, | ocupa un píxel, despois hai 2 en negro; un para o punto entre as barras, dous en negro, outro para a seguinte barra |, dous en negro, tres para representar o 2 e dous en negro de separación entre esto e o eixo. En total son 13 píxeles dedicados os caracteres do eixo, e o resultado será: | • | ²

En canto ó eixo de abscisas, queremos representar unha K. Por iso, deixamos 2 píxeles de separación entre o eixo e a letra, e utilizaremos 5 píxeles para representala en canto á súa altura e 4 para o ancho.

Tanto os eixos como as letras son brancas, por iso esta parte é común ás tres compoñentes.

b)Diferencias entre RGB.

Unha vez descrita a parte común ás tres compoñentes, agora imos falar delas unha a unha. As únicas diferencias entre eles se atopan na zona de datos a representar (descontando na zona activa o espacio dos bordes, os eixos e as letras). Nesta zona, pixel_x ten valores entre 71 y 582 e pixel_y varía entre 5 e 464.

Analicemos primeiro a división de cores en horizontal. A orde desta división será Vermello, Laranxa, Amarelo, Verde, Cyan, Azul, Violeta e Maxenta (a segunda metade será simétrica). Se temos 512 píxeles e 16 colores, teremos 32 píxeles por barra. Logo, activaremos o vermello (en primeiro lugar os 8 bits a 1) para a barra Vermella, Laranxa, Amarela, desactivarémolo para o Verde, Cyan e Azul, e activarémolo para o Violeta e o Maxenta (o mesmo para os seus correspondentes simétricos). É dicir, R permanecerá activo dende 71 a 166, inactivo dende 167 ata 262, activo desde 263 ata 390, inactivo dende 391 ata 486 y activo dende 487 ata 582.

Para incluir intensidades de cores, distinguiremos catro intervalos de píxeles en vertical: 5-119, 120-234, 235-349, 350-464. No máis baixo (nivel máis alto das barras) temos as cores a maior intensidade, logo as compoñentes presentes na cor deben estar a nivel máximo (todo uns). Por exemplo, o vermello debe valer máximo para Vermello, Laranxa e Amarelo (en vermello é a única compoñente, en laranxa o máis forte e en amarelo a medias co verde) máximo en Maxenta, y á metade do máximo en violeta (é máis forte o azul). Nos otros cores (Cyan, Azul e Verde) empezará nun valor e irá baixando a medida que subamos á barra. Esto é difícil de aclarar. Pensemos no Cyan, que ten verde e azul a partes iguais. No nivel máximo dea barra (píxeles 5-119), ámbolos dous están ao máximo e o vermello a 0 (de esta forma temos Cyan intenso). Nos posteriores intervalos o vermello vai aumentando, mentres os outros permanecen constantes, o cal equivale a sumarlle branco á cor e restarlle intensidade ou brillo. Pódense seguir razoamentos similares para os demais cores, establecendo os valores que debe ter a compoñente vermella para cada intervalo.

Os razonamentos sobre as compoñentes verde e azul son os mesmos, o único que varían son os números, polo tanto non os repetiremos.

Por último, cabe destacar que todas as asignacións se fan sobre compoñentes auxiliares, debido á lectura en memoria dos datos. En cada ciclo léense os datos do ciclo seguinte para procesalos e asígnanse as compoñentes auxiliares. Desta forma, non afectamos ao píxel que se está representando. Cando termina o ciclo, os valores das compoñentes auxiliares pásanse ás compoñentes reais.



Bloque sincronismo interfaz VGA

Empezaremos por la definición de las constantes. Como ya explicamos en los fundamentos de funcionamiento del monitor VGA, tanto la línea horizontal como la vertical se dividen en 4 zonas: zona activa, pórtico anterior, retorno y pórtico posterior. Cada una ocupa un número determinado de los 800 píxeles que contiene cada línea horizontal y de las 520 líneas (cambiamos este valor de 525 a 520 para que la tasa de píxel fuera exactamente 25 MHz) que contiene cada línea vertical. Por tanto, lo primero que hacemos es definir estas constantes.


constant HD: integer:=640; --h.datos
constant HF: integer:=16; --h.pórtico_anterior
constant HB: integer:=48; --h.pórtico_posterior
constant HR: integer:=96; --h.retorno
constant VD: integer:=480; --v.datos
constant VF: integer:=9; -- v.pórtico_anterior
constant VB: integer:=29; -- v.pórtico_posterior
constant VR: integer:=2; -- v.retorno

Nuestro siguiente paso será generar el reloj de píxel, y lo haremos a partir de impulsos del reloj del sistema. Como el reloj general es de 100 MHz y el de 25 MHz, en lugar de implementar un reloj independiente (solución que obviamente deteriora el sincrionismo o lo dificulta), modelamos un contador módulo cuatro, de forma que generaremos una señal que permanezca a nivel alto o bajo cuatro ciclos del reloj del sistema.

En cuanto a la construcción de las líneas de sincronismo, partiremos en el momento en que ambas señales se ponen a nivel alto (píxel 751 y línea 491). Por tanto, en este punto las señales de pixel_x y pixel_y tomarán estos valores, mientras que las señales sinc_hor y sinc_ver pasan de nivel bajo al alto. Esta será la situación a la que se vuelve tras pulsar un RESET.





A continuación, iremos incrementando los valores de pixel_x en cada flanco ascendente del reloj de pixel y de pixel_y cada vez que pixel_x llega a 799 (en este caso en vez de incrementarse se pone de nuevo a cero). Por su parte, pixel_y ser reinicia a cero cuando está en el valor 519 y debe actualizarse. Cuando pixel_x llegue a 655 (todos estos valores están controlados en el código por las constantes, para poder cambiarlas sin cambiar el código), se cambia sinc_hor a nivel bajo. Si todo ha ido bien, el tiempo que habrá transcurrido desde que sinc_hor se puso a nivel alto serán 28.16 us.








Del mismo modo, la señal volverá a activarse cuando pixel_x llegue de nuevo a 751, debiendo haber transcurrido un tiempo a nivel bajo de 3,84 us (tiempo total de una línea 28.16 + 3.18 = 32 us = 800/25 MHz.





De la misma forma, la bajada de sinc_ver se produce cuando pixel_y alcanza el valor 489, estando a nivel alto durante 16.736 ms.








Subirá de nuevo cuando pixel_y valga 491, habiendo transcurrido 0.064 ms mientras estaba a nivel bajo (tiempo de un barrido de pantalla 16.576 + 0.064 = 16.64 ms = 800*520 / 25 MHz.






De esta forma se consiguen las señales de sincronismo necesarias para el monitor. La señal de activo se pone a 1 solo cuando pixel_x está entre 0 y 639 y pixel_y está entre 0 y 479 (ambas condiciones a la vez).

lunes, 11 de mayo de 2009

Unidade de Cálculo de Módulos: Unidade de Red. / Trunc. e Saturación

Documentación "definitiva" sobre o circuito denominado Unidade de Redondeo/Truncado e Saturación, que forma parte da Unidade de cálculo de Módulos. En principio é definitiva, pero cabe a posibilidade de que sufra pequenas variacións.

-----------------------------------------------------------------------------

----------------------------------------------------------------------------

Modelo VHDL do circuito de redondeo/truncado e saturación.

-----------------------------------------------------------------------------

1.- Descrición do circuito.


Este circuito permite converter un dato numérico de 19 bits sen signo a un valor de 9 bits mediante unha operación de escalado e a posterior saturación do resultado. Ambos datos, no que segue, considéranse valores enteiros.

O escalado realízase sempre por un factor que é menor ou igual á unidade, o que en xeral dá lugar a cifras decimais que deben ser eliminadas, ben por un proceso de redondeo ou ben por truncamento directo. Para a elección dunha ou outra alternativa só é necesario varia-las opcións de implementación adecuadas (os parámetros xenéricos do modelo VHDL).

O factor de escalado pode establecerse dinamicamente (durante a operación do circuito) a través dun bus de entrada de dúas liñas, sendo sempre da forma 2^-(3*B) con B o valor numérico dese bus: 0,1,2 ou 3. Isto implica que o escalado é equivalente (e así se implementa na circuitería) a un desprazamento á dereita de 0, 3, 6 ou 9 bits, cun posíbel axuste posterior cando se seleccione o modo de traballo con redondeo.

Por último, o resultado do escalado pode limitarse a un valor arbitrario entre 1 e 2^9-1, que se fixa durante o deseño do circuito e unha vez implementado este permanece constante para tódalas operacións. Con esta saturación evítase o problema que se derivaría da asignación directa dos 9 bits menos significativos do valor escalado á saída: se algún bit de maior peso estivese activo obteriamos o mesmo valor ca no caso de que non estivera.


2.- Estructura interna.




No esquema UD_RD_SAT.jpg represéntase a forma máis xeral da Unidade de Redondeo/ Truncado e saturación. En función das opcións de implementación (isto é, os valores que asignemos ós parámetros xenéricos no modelo VHDL) podemos cambia-la estructura interna e conseguir dende un circuito totalmente combinacional a un circuito con procesado en pipeline e distintos niveis, así como seleccionar escalados con redondeo ou con truncado.


Os parámetros xenéricos afectan ó circuito da seguinte maneira:

- O parámetro REDONDEO pode tomar valor true ou false; cando se establece a true o circuito redondeará os valores escalados, mentres que se se establece a false estes só se truncarán. No esquema, a zona do interior do recadro punteado só existe cando se establece un modo de redondeo; en caso contrario só haberá un bus dende a saída do dato escalado ata a entrada da seguinte etapa.

- O parámetro NIVEL_PIPELINING pode tomar os valores 0, 1 ou 2, cos que se consegue varia-la cantidade de etapas de pipeline do circuito:

- Co valor 0 non se emprega ningún rexistro de pipeline: o circuito de redondeo/truncado e saturación será a cascada dunha serie de etapas combinacionais conectadas directamente, e polo tanto, posuirá un certo retardo combinacional (da orde dos 10ns nunha FPGA Virtex2pro) que haberá que ter en conta no deseño.

- Co valor 1 só se implementa un ou dous rexistros de pipeline, dependendo de se se elixe o modo de traballo con redondeo ou con truncamento: con redondeo instanciarase un rexistro intermedio e outro para os datos de saída (rexistros e biestábeis 2 e 4 no esquema), mentres que con truncamento só este último (rexistro e biestábel 4). Neste caso o circuito introduce unha latencia inicial de dous ciclos de reloxo en modo de redondeo, e de un ciclo en modo de truncado.

- Co valor 2 impleméntanse tódolos posíbeis rexistros de pipeline: un entre cada dúas etapas combinacionais máis outro final para os datos de saída. Se se traballa con modo de redondeo o circuito pasará polo tanto a ter catro etapas pipeline (rexistros e biestábeis 1, 2, 3 e 4) co que introducirá unha latencia de catro ciclos; no modo de truncado o circuito posuirá dous rexistros (r. e b. 3 e 4) o que supón unha latencia de só dous ciclos.

- O parámetro VALOR_MAXIMO determina o valor de saturación para a última etapa combinacional do circuito. Pode fixarse a calquera valor enteiro entre 1 e 511, e non inflúe na estructura do circuito, só no funcionamento.



3.- Descrición dos terminais de entrada e saída.


Os terminais de entrada son:


· D_IN: bus de datos de entrada de 19 bits.


· DV_in: sinal de datos válidos á entrada. Este sinal só é relevante cando se realiza unha implementación con pipelining: neste caso o valor establecido no bus D_IN captúrase no primeiro rexistro de pipelining cando DV_in está a nivel alto e ocorre un flanco de reloxo ascendente. Cabe destacar que o tempo de establecemento para este rexistro dependerá do número de etapas combinacionais que deba atravesa-lo sinal de entrada antes de acada-la entrada do rexistro, ou o que é o mesmo, do nivel de pipelining establecido.

Se se realiza unha implementación totalmente combinacional este terminal pontéase directamente ó terminal de saída DV_out.


· Escala: bus de dúas liñas para a elección do factor de escala.


· Escala_WE: sinal de habilitación de escritura para o bus Escala. A captura destes datos ocorrerá cando Escala_WE estea a nivel alto e se produza un flanco de reloxo ascendente. O valor de Escala non forma parte da estructura pipeline do circuito: o rexistro só evita a necesidade de manter estábel o dato no bus Escala constantemente.



Os terminais de saída son:


· D_OUT: bus de saída de datos de 9 bits.


· DV_out: sinal de datos válidos no bus D_OUT. Este sinal actívase durante un ciclo de reloxo por cada dato válido que se presente no bus D_OUT cando se realiza unha implementación con pipeline; noutro caso reflexará sempre o valor do terminal DV_in, xa que se pontean directamente.

-----------------------------------------------------------------------------

-----------------------------------------------------------------------------


Unidade de Cálculo de Módulos (I): Documentación

Esta é a documentación da Unidade de Cálculo de Módulos, supostamente definitiva. Se se produce algún cambio indicarese nestas liñas.

-----------------------------------------------------------------------------
----------------------------------------------------------------------------

Modelo VHDL da Unidade de cálculo de módulos.

-----------------------------------------------------------------------------
----------------------------------------------------------------------------
-----------------------------------------------------------------------------

1.- Descrición do circuito:

Este circuito efectúa o cálculo do módulo de números complexos en forma cartesiá z = a + jb, onde a e b son a parte real e imaxinaria do número respectivamente e j é a unidade imaxinaria. Os valores a e b deben estar expresados con 18 bits en complemento a 2, mentres que o módulo de z proporciónase nun formato sen signo de 9 bits.
No seu interior este circuito implementa directamente a expresión
|z| = (a^2 + b^2)^(1/2)
seguindo a orde de operacións lóxica: primeiro realiza o producto de cada parte por si mesma, logo suma os resultados, e por último calcula a raíz cadrada da suma utilizando un IPCore de Xilinx que implementa unha variante do algoritmo Cordic. Este IPCore proporciona resultados enteiros de 19 bits sen signo, redondeando tódalas cifras decimais sempre que sexa necesario.
A continuación os valores dos módulos de 19 bits deben ser adaptados ó bus de saída de datos, de 9 bits de ancho. Para isto intercálase entre o IPCore Cordic e o bus de saída un circuito de redondeo/truncado e saturación (UD_RD_SAT). Este circuito permite escala-lo valor de entrada por unha potencia de dous e finalmente limita-dos valores de saída a unha constante arbitraria, evitando así problemas de desbordamento. Os detalles sobre este circuito atópanse no arquivo redondeo_saturación.vhd.



2.- Estructura do circuito:


O circuito está deseñado como unha estructura de procesado de datos en pipeline. Posúe tres etapas en serie:
• Unha etapa inicial na que se calcula o cadrado das partes real e imaxinaria e se suman, isto é, o módulo ó cadrado do número complexo de entrada.
• Unha segunda etapa co IPCore que implementa o algoritmo Cordic, no que se computa a raíz cadrada do módulo ó cadrado.
• Unha etapa final de adaptación do valor do módulo de 19 bits ó bus de saída de 9 liñas, mediante o circuito de redondeo/truncamento e saturación.
A etapa inicial e o IPCore Cordic realizan os seus cálculos con pipelining sempre; no entanto, o circuito de adaptación por redondeo/truncamento e saturación pode realizar pipelining ou non dependendo da asignación ós parámetros xenéricos: pode ser dende un circuito totalmente combinacional ata implementar múltiples etapas de pipelining, en función das asignacións ós parámetros xenéricos do modelo VHDL da Unidade de Cálculo de Módulos.

Para que a Unidade de Cálculo de Módulos funcione correctamente o IPCore Cordic debe xerarse coas seguintes características:
- Debe implementa-la operación raíz cadrada, como é lóxico.
- Debe elixirse unha estructura con pipeline óptimo ou máximo. Unha ou outra elección só repercute na frecuencia máxima de traballo do circuito completo, xa que de toda a circuitería da unidade de cálculo de módulos, este IPCore é o elemento máis limitativo.
- O formato de datos debe ser enteiro sen signo ("unsigned integer"), e é necesario que o IPCore posúa terminais CE, SCLR, ND e RDY.
- As entradas e saídas deben posuír rexistros obrigatoriamente, de 36 bits e 19 respectivamente.
Os demáis parámetros poden elixirse a vontade, o circuito funcionará exactamente igual, aínda que para que o redondeo se realice tal e como aquí se describe debe marcarse a opción "Roud Pos Inf".


3.- Descrición dos terminais de entrada e saída:

As entradas do circuito son as seguintes:

• X_RE, X_IM: buses de entrada das partes real e imaxinaria.

• DV_IN: liña activa a nivel alto e síncrona que indica que existen datos válidos nos buses X_RE e X_IM. Cando este terminal se atopa a nivel alto e se produce un flanco de reloxo ascendente os datos de ambos buses son capturados para comeza-lo seu procesado inmediatamente. Grazas á estructura pipeline da unidade de cálculo de módulos é posíbel cargar un par de datos de entrada (a parte real e a parte imaxinaria) en cada ciclo de reloxo mandendo a nivel alto a liña DV_IN. A única restricción é que se debe asegura-la estabilidade dos datos de ambos buses cando se procuza o flanco ascendente e polo tanto a súa captura.

• escala: Bus de dúas liñas onde se especifica un valor asociado ós desprazamentos á dereita dos módulos da DFT de 19 bits antes do circuito de saturación (zoom). Permítense catro valores de escala, dende 0 (máis detalle, sen redondeo/truncamento) a 3 (mínimo detalle, máximo redondeo/truncamento). A cantidade de bits desprazados á dereira é de 3*(Escala).

• escala_WE: terminal de habilitación de captura do valor do bus Escala. A captura ocorre sempre que escala_WE estea a nivel alto e se produza un flanco ascendente.

Estes dous sinais están directamente conectados nas entradas cos mesmos nomes do circuito de redondeo / truncamento e saturación.

As saídas do circuito son as seguintes:

• Modulo: bus de datos síncrono no que se proporcionan os valores dos módulos calculados polo circuito. Cada un destes valores aparece durante un único ciclo de reloxo.

• DV_OUT: sinal activo a nivel alto e síncrono que indica que no bus Modulo existen un dato válido. Este sinal actívase un ciclo de reloxo por cada dato de saída presentado polo circuito, manténdose a nivel alto durante varios ciclos se nestes se proporcionan varios resultados válidos consecutivos. A captura do valor do bus Modulo debería producirse sempre que DV_OUT se atopa a nivel alto e ocorre un flanco ascendente de reloxo, xa que é neste momento no que se asegura sempre a estabilidade dos datos.


Os portos de simulación permiten obter información sobre os cálculos internos da unidade: X_mod2_SIM amosa cada un dos módulos ó cadrado calculados e X_mod_SIM a saída do core Cordic, isto é, a raíz cadrada de X_mod2_ SIM. Non existe ningún sinal indicador de datos válidos, co que o uso destes valores necesita analiza-la latencia dos datos, e é pouco aconsellábel.


4.- Implementación:

O valor dos parámetros xenéricos determina a estructura interna do circuito de redondeo / truncado e saturación. Están directamente asignados ós parámetros xenéricos da instancia deste circuito, co que afectan exclusivamente ó seu funcionamento. A súa descrición atópase na documentación do modelo vhdl do circuito de redondeo / truncado e saturación.
Brevemente:
• O parámetro REDONDEO indica se o cálculo do módulo se realiza con redondeo intermedio (REDONDEO = true, precisa máis recursos) ou con truncado (REDONDEO = false, menos recursos empregados).
• NIVEL_PIPELINING serve para selecciona-la estructura do circuito de redondeo e saturación. Canto máis alto sexa este valor (dentro dos posíbeis) máis etapas de pipeline se engaden no circuito, o que permite que traballe a unha frecuencia de traballo maior a costa dunha maior latencia inicial. Os valores posíbeis son 0 (sen pipeline: circuito totalmente combinacional), 1 (número intermedio de rexistros de pipeline) e 2 (impleméntanse tódolos rexistros de pipeline posíbeis).
• VALOR_MAXIMO indica o valor ó cal se produce a saturación.

jueves, 7 de mayo de 2009

Estado do interfaz do monitor VGA

Ola!!

A semana pasada rematamos o modelado do interfaz do monitor VGA (que inclúe o bloque de sincronismo e o cálculo dos píxeles RGB que se mandan ó conversor FMS3818). Nunha primeira proba (para comprobar o correcto funcionamento, os detalle e colores virán unha vez nos cercioremos de que todo funciona), implementamos todo en branco e negro, cun eixo vertical e outro horizontal. Se todo vai segundo o esperado (que todo funione corretamente o 15 de maio), incluiremos unha escala de colores en vertical (segundo o valor do módulo da FFT) e en horizontal (seguno do índice da FFT que se está visualizando), e se imos rápido, incluiremos tamén as letras que nos din qué se representa no eixo vertical e o que se representa no horizontal (módulo da FFT e índice, respectivamente).

Simulamos o circuito tanto funcional como temporalamente, con resultados positivos. Sen embargo, á hora da proba coa placa e o monitor, nos conseguimos ver nada neste último. Estamos intentando solucionar este problema, e esperamos conseguilo antes do venres 15 de maio, para poder xuntar o interfaz con resto do circuito do analizador (conversor AC97 e cálculo da FFT).

En canto o funcionamento destas probas que se están realizando sexa correcto, publicaremos unha nova entrada informando!!

Un saúdo!

martes, 5 de mayo de 2009

Módulo FFT(III): Documentación "Definitiva"

Esta é a suposta versión definitiva da documentación do Módulo FFT. Saúdos!


-----------------------------------------------------------------------------

-----------------------------------------------------------------------------

-----------------------------------------------------------------------------

Modelo VHDL do Módulo FFT

-----------------------------------------------------------------------------

-----------------------------------------------------------------------------

-----------------------------------------------------------------------------

-----------------------------------------------------------------------------

----------------------------------- Pablo Losada Sanisidro.

-----------------------------------------------------------------------------

-----------------------------------------------------------------------------

1.- Descrición do Módulo FFT:

Este circuito realiza o cálculo do módulo da DFT de 512 puntos dun sinal real. As mostras do sinal de entrada x(n) deben estar cuantificadas con 18 bits en Ca2, mentres que os datos presentados á saída teñen 9 bits de ancho e veñen expresados nun formato sen signo.



Internamente o circuito utiliza o algoritmo FFT (Fast Fourier Transform) para o cálculo das mostras complexas da DFT, e unha vez calculadas estas, obtén os seus módulos elevando as partes real e imaxinaria ó cadrado, sumando ambos resultados, e aplicando o algoritmo Cordic modificado para o cómputo da raíz cadrada disto. Todos estes pasos lévanse a cabo nos dous compoñentes fundamentais que forman a ruta de datos do Módulo FFT: un circuito que implementa o algoritmo FFT e unha Unidade de cálculo de Módulos, que opera sobre os resultados do anterior.

Para evitar desbordamentos durante o proceso de cálculo da FFT existe a posibilidade de aplicar un desprazamento á dereita ó resultado dalgunhas mariposas dun certo número de bits, que se pode elixir a través dun bus de entrada. Isto supón que cando se empregue esta posibilidade o resultado da FFT non coincida exactamente coa DFT de 512 puntos do sinal x(n), senón cunha versión escalada en ampritude desta. A expresión do factor de escala como función dos desprazamentos á dereita é

S = 2^-(sum(bi))

onde bi é o número de bits desprazados á dereita á saída da mariposa da i-ésima etapa da FFT.

En canto á Unidade de Cálculo de Módulos, esta acada internamente unha precisión de 19 bits nos seus resultados, polo que para presentalos no bus de saída de 9 bits faise necesaria unha adaptación de valores. Para isto existe un circuito de saturación que evita os erros por desbordamento que se producirían cunha asignación directa dos 9 bms ás liñas do bus. O funcionamento deste circuito é tal que cando a magnitude dos datos de entrada é igual ou inferior a un límite arbitrario (entre 1 e 511) estes refléxanse na saída sen verse alterados, mentres que todos aqueles que o superen quedan saturados a este valor.

Adicionalmente a Unidade de Cálculo de Módulos ofrece a posibilidade de realizar un desprazamento á dereita sobre os valores dos módulos de 19 bits de precisión antes da etapa de saturación. Os bits que se desprezan pódense truncar simplemente ou ben redondear, o que supón que cando estes bits superen certo valor increméntase nunha unidade a parte non desprezada. Ademais, a cantidade de bits a desprazar elíxese a través dun bus de entrada, podendo ser de 0, 3, 6, ou 9 bits.

O modo de operación con redondeo ou con truncamento, así coma o límite de saturación da saída, pode seleccionarse durante a implementación do Módulo FFT mediante asignacións ós parámetros xenéricos do seu modelo VHDL.

Por último, o Módulo FFT posúe buses e sinais especiais á saída que lle permiten gobernar directamente unha memoria RAM síncrona de alomenos 512 posicións e palabras de datos de 9 bits de ancho.

Cabe destacar que o desprazamento previo á saturación permite realizar unha especie de 'zoom' nos datos de saída, xa que se non se realiza ningún desprazamento obteriámo-los módulos da DFT co máximo grao de resolución posíbel en 9 bits, con aqueles que superasen o máximo valor representábel saturados. Variando o número de bits desprazados antes da saturación pérdese resolución e precisión, pero a cambio conservarianse as ampritudes relativas das compoñentes espectrais, xa que os desprazamentos equivalen a escalados por unha potencia de dous menor ca 1 (é dicir, 2^-b), co que xa non serían necesarias as saturacións.




2.- Terminais de Entrada e Saída:

Os buses e sinais de entrada do circuito son os seguintes:

· Nova_Mostra: sinal activo a nivel alto e síncrono que indica que existe unha nova mostra dispoñíbel no bus xn. A captura do valor da mostra xn ten lugar no seguinte flanco ascendente do reloxo á detección do sinal Nova_Mostra activado. É dicir, unha vez que se estableza un nivel alto en Nova_Mostra = '1' e ocorra un flanco ascendente no reloxo, a circuitería interna memorizará o valor do bus xn no próximo flanco ascendente do sinal de reloxo.

· Inicio: Sinal activo a nivel alto e síncrono que solicita o inicio dun novo ciclo de cálculos no circuito, é dicir, fai que este se prepare para a carga de 512 mostras, o cálculo da súa FFT e a posterior descarga dos resultados. A captura deste sinal efectúase nos flancos ascendentes do reloxo, e ten efecto sempre e cando o circuito non estea xa en proceso de carga de datos, cálculo dunha FFT, ou realizando a descarga de resultados: nestes casos este sinal Inicio ignórase.

· xn: Bus onde se introduce o valor de cada mostra de entrada (18 bits en Ca2).

· scale_sch: Bus de 18 bits no que se establece o valor de escalado anti-overflow para os cálculos internos da FFT. As liñas do bus divídense en parellas que indican o número de desprazamentos á dereita do resultado de cada mariposa ou etapa da circiutería da FFT (1, 2, 3 ou 4 bits desprazados), de maneira que a parella de bits menos significativos correspóndese coa primeira etapa, a seguinte parella coa segunda, e así ata a novena parella, asociada á última etapa da FFT. O número de desprazamentos codifícase en binario natural nos dous bits da parella.

· scale_sch_we: Sinal de habilitación de captura do valor de escalado anti-overflow. A captura do valor do bus scale_sch ocorre cando se produce un flanco ascendente no sinal de reloxo e scale_sch_we ='1'.

· escala: Bus de dúas liñas onde se especifica un valor asociado ós desprazamentos á dereita dos módulos da DFT de 19 bits antes do circuito de saturación (zoom). Permítense catro valores de escala, dende 0 (máis detalle, sen redondeo/truncamento) a 3 (mínimo detalle,máximo redondeo/truncamento). A cantidade de bits desprazados á dereira é de 3*(Escala).

· escala_WE: terminal de habilitación de captura do valor do bus Escala. A captura ocorre sempre que escala_WE estea a nivel alto e se produza unflanco ascendente.

Os buses e sinais de saída son os seguintes:

· ram_we: Sinal síncrono de habilitación de escritura para a RAM conectada á saída.Este sinal actívase durante un ciclo de reloxo completo cando existe unvalor válido no bus xk_mod. A captura deste valor debe producirse noseguinte flanco positivo de reloxo dende o momento no que se activa ram_we(memoria RAM con escritura síncrona).

· ram_addr: Bus de 9 bits de direccionamento para unha memoria RAM síncronade saída. A cada un dos módulos calculados da DFT asóciaselle unha posiciónda memoria RAM, comezando dende 0 para a mostra 0 da DFT.

· xk_mod: Bus de 9 bits co valor de cada un dos módulos das mostrasda DFT. Nos ciclos nos que se active o sinal ram_we existirá undato válido neste bus, que estará estábel no momento no que ocorra oseguinte flanco ascendente do reloxo.

· fin: sinal síncrono que indica o fin dun ciclo de carga, cálculo e descargacompleta de datos do Módulo FFT. Este sinal actívase durante un ciclo dereloxo unha vez que tódolos valores dos módulos da DFT aparecesen nos busesxk_mod, xunto coa correspondente activación do sinal ram_we e adirección apropiada no bus ram_addr.

· CARGA_busy: sinal síncrono que se activa durante toda a fase de carga devalores das mostras x(n). Actívanse cando se comeza o proceso de carga dedatos,e desactívase unha vez que se cargan as 512 mostrasdo sinal de entrada e comezan os cálculos.

· FFT_busy: sinal síncrono que se activa durante os cálculos da FFT.Actívase logo do fin do proceso de carga e desactívase xusto antes docomezo da descarga de datos.

· DESCARGA_busy: sinal síncrono que se activa durante a descarga dosmódulos da DFT calculada. Permanece activada durante toda a fase de descarga de datos, e unha vez queaparece na saida o último módulo calculado, desactívase.

· Ovflo: sinal síncrono que se activa cando se produce un overflow duranteo cálculo da FFT das mostras x(n). Permanece activado durante o resto dociclo de cálculos e a descarga, e desactívase no inicio do seguinte ciclo ou ben ante a activación dun reset.

Os terminais de simulación reflexan valores calculados internamente, ese non se empregan deben deixarse abertos na instanciación (open).

· XK_IM_SIM, XK_RE_SIM: partes real e imaxinaria de cada mostra da DFT.

· X_mod_SIM, X_mod2_SIM: módulo e módulo ó cadrado de cada mostra da DFT.

· FFT_DV_SIM: sinal síncrona activa a nivel alto que se activa candoaparecen datos válidos nos buses XK_**_SIM, é dicir, durante a descarga dedatos do circuito que calcula a DFT.

· FFT_CE_SIM: sinal síncrona de habilitación de reloxo para o circuito que calcula a DFT. Só para labores de depuración: non se pode asignar dende o exterior.

· RFD_SIM: sinal síncrona que indica que o circuito de cálculo da FFT está listo para recibir datos de entrada. Só se emprega para depuración.

· XN_INDEX_SIM: bus que indica o número de mostra de saída durante a descarga de datos do circuito que calcula a FFT, dende 0 a 511.

3.- Funcionamento do circuito:

O funcionamento do Módulo FFT é moi simple:

- Dende o arranque en frío é necesario activar o sinal Reset durante un ciclo de reloxo alomenos. Isto establece as condicións iniciais básicas na circuitería de control.

- O primeiro paso antes de comeza-los cálculos co Módulo FFT é proporcionar un valor de escala anti-overflow. Para iso establécese o valor desexado no bus scale_sch e logo actívase durante un ciclo de reloxo o sinal scale_sch_we. Estas dúas operacións poden realizarse nun único ciclo de reloxo, pois o único requisito para que se completen correctamente é que os datos do bus estean estábeis no flanco ascendente do sinal de reloxo no que se capturan. O valor de escala anti-overflow queda memorizado entre os sucesivos ciclos de cálculos, co que só é necesario proporcionalo unha vez despois de cada reset efectuado.

- O seguinte paso é proporcionar un valor de escala de representación (ou zoom) para a adaptación dos resultados. Para isto é necesario activar un ciclo de reloxo o sinal escala_WE e establecer simultaneamente o valor desexado no bus Escala. Esta operación pode repetirse en calquera momento excepto durante as descargas de datos, momentos nos que se opera co valor introducido. Ademais sempre é absolutamente necesario proporcionar alomenos unha escala de representación logo de cada reset.

- A continuación o circuito está listo para a activación do sinal Inicio. Se se establece un nivel alto durante un ciclo de reloxo neste terminal o Módulo FFT realizará inmediatamente as operacións internas necesarias para prepararse para a carga de datos. Estas operacións precisan tres ciclos de reloxo para completarse, nos que se ignoran por completo tódolos terminais de entrada excepto o RESET. Unha vez transcorridos, o circuito estará listo para a carga de 512 mostras do sinal a analizar a través do bus xn e a liña Nova_Mostra.

- A carga dunha mostra realízase activando o sinal Nova_Mostra durante un ciclo de reloxo, e establecendo o valor da mostra no bus xn. A memorización do valor do bus prodúcese no seguinte ciclo de reloxo ó da activación de Nova_Mostra, no instante do flanco ascendente de reloxo, co que a única restricción para a operación de carta é que o dato do bus xn se atope estábel no momento da súa captura. É dicir, o dato de entrada pode establecerse no bus no mesmo ciclo cá activación da liña Nova_Mostra, sempre que logo se manteña durante o seguinte ciclo de reloxo, no que realmente se memoriza.

- Cando se carguen as 512 mostras o circuito procederá ó cálculo da súa DFT co algoritmo FFT; logo calculará os módulos de cada mostra espectral, e finalmente tras un tempo de latencia proporcioná os resultados nos buses de saída de forma secuencial e continua. As operacións realizadas en cada momento amósanse nos terminais FFT_busy, CARGA_busy, DESCARGA_busy, e FIN.

RESTRICCIÓNS:

O funcionamento do Sistema Secuencial Síncrono que controla a carga de datos impón

os seguintes límites:

- Entre a activación de Inicio e a primeira activación de Nova mostra han de pasar, alomenos, TRES ciclos de reloxo, nos que se prepara a circuitería interna para a recepción de datos. Nestes ignórase Nova_Mostra, e polo tanto non se realiza ningunha carga.

- A carga dunha mostra precisa de dous ciclos de reloxo: no primeiro actívase Nova_Mostra, e no segundo adquírese realmente o valor do bus xn, de forma exclusiva. É dicir, NON é posíbel realizar unha carga contínua de mostras, solapando a captura dunha mostra coa activación do sinal Nova_Mostra para a seguinte.

- Tra-la activación do sinal FFT_Fin, deben transcorrer dous ciclos de reloxo antes dunha nova activación do sinal Inicio. Isto débese ás operacións internas da circuitería de control, que debe deixar en espera a toda a circuitería operativa.

4.- Estructura e implementación:

O Módulo FFT descomponse internamente en catro bloques fundamentais:

· Un Sistema Secuencial Síncrono de Control, que goberna os demáis circuitos do módulo, controla os procesos de carga e descarga de datos, etc.

· Unha implementación do algoritmo FFT basado no IPCore FFT v3.0 de Xilinx (UD_FFT).

. Un circuito de cálculo do módulo de cada mostra da DFT e procesado posterior, incluindo o circuito de escala ou desprazamento para a representación ( zoom)e un circuito de saturación (UD_MODULO).

· Un contador de 9 bits que se utiliza con dous propósitos: serve como xerador das direccións do bus ram_addr e intervén nas labores de control do SSS no proceso de carga de datos.

Estes últimos tres compoñentes integran unha unidade operativa ou ruta de datos do Sistema Secuencial de Control.

O modelo VHDL do Módulo FFT posúe tres parámetros xenéricos cos que se pode controlar a estructura interna da circuitería que forma o circuito de cálculo de módulos (UD_MODULO). A descripción de cada un e o seu funcionamento atópase no arquivo fonte deste circuito.

Por último, para que o Módulo FFT funcione correctamente o IPCore FFT de Xilinx debe posuir certas funcionalidades, co que é preciso establece-las seguintes opcións á hora da súa xeración:

* A lonxitude da DFT debe ser fixa e de 512 puntos, e debe empregarse unha única canle.

* Débese seleccionar a estructura Radix 2 lite ou Radix 2 como estructura das mariposas.

* Os datos de entrada deben estar en punto fixo e ter un ancho de 18 bits.

* Internamente debe empregar aritmética escalada, e é obrigatorio implementa-los terminais SCLR, CE e OVFLO.

O resto de parámetros poden elixirse arbitrariamente: a orde de descarga dos datos de saída só afecta á orde na que estes se presentan nos bus de saída, e o modo de truncado e a lonxitude dos factores de fase só afectan á precisión dos cálculos.

-----------------------------------------------------------------------------

-----------------------------------------------------------------------------

----------------------------------------------------------------------------