27
1 Grado en Ingeniería Electrónica de Comunicaciones Curso académico 2015-2016 Asignatura Diseño Electrónico Departamento de Electrónica Universidad de Alcalá Controlador para Códec de Audio Agüero Zeballos, Sebastián Alonso Bitai, Anne Mária

Controlador de Codec de Audio para una FPGA

Embed Size (px)

DESCRIPTION

En esta memoria se explica el desarrollo de la construcción de un controlador de un codec de audio para FPGA

Citation preview

Page 1: Controlador de Codec de Audio para una FPGA

1

Grado en Ingeniería Electrónica de Comunicaciones Curso académico 2015-2016 Asignatura Diseño Electrónico Departamento de Electrónica Universidad de Alcalá

Controlador para Códec de Audio Agüero Zeballos, Sebastián Alonso Bitai, Anne Mária

Page 2: Controlador de Codec de Audio para una FPGA

2

Índice Introducción ................................................................................................................ 3

1.- Detector de flanco de subida y de bajada configurable. ................................ 4

2.- Doble detector de flanco de subida y de bajada basado en un modelo genérico. ...................................................................................................................... 9

3.- Reset and sync generation. .............................................................................. 11

4.- Output Frame ...................................................................................................... 16

5 y 6.- Control de Volúmen y Frecuencia, y modelo general final. .................. 21

7.- Conclusiones ...................................................................................................... 27

Page 3: Controlador de Codec de Audio para una FPGA

3

Introducción

En este laboratorio se pretende realizar un diseño sintetizable mediante código

VHDL para controlar un sistema integrado de la FPGA spartan 6, el LM4550,

un CODEC de audio. Para llevar a cabo este diseño se ha desglosado el

mismo en diferentes entidades, para facilitar el entendimiento de cada paso, y

hacer un análisis localizado, que resulta más sencillo a la hora de encontrar

posibles fallos durante su desarrollo.

El diseño consiste en un top system que engloba a todas las demás entidades,

y contiene el dcm, el codec_controller, y en la versión final del diseño también

incluye una entidad llamada vol_freq_control.

El dcm (digital clock manager) se utiliza como herramienta para alinear todos

los relojes internos del diseño. A veces puede existir cierto desfase entre

relojes y este módulo lo corrige. Se genera utilizando un coregen, así que no

tiene mayor diseño propio.

El codec_controller contiene a las entidades que realmente se van a diseñar en

esta práctica (aparte del vol_freq_control), y estas son: double_edge_detector,

output_frame, y rst_and_sync_generation.

La unidad más básica de este diseño, es un detector de flancos, con el que

luego se construye un detector doble de flancos. Esta unidad se utilizará para

detectar flancos de una señal de reloj proporcionada por el códec (bit_clk) que

da la temporización de los bits. Esta señal que detecta los flancos de bit_clk se

utilizará para sincronizar todo el sistema mediante clock enables

principalmente.

La entidad rst_and_sync_generation es la encargada de generar un reset inicial

para resetear todos los componentes del códec, y se ha elegido un valor de 5

us para su duración. Además de esto, también es la encargada de generar una

señal de sincronismo que se activa a nivel alto durante los primeros 16 bits de

cada trama generada en el output_frame.

Page 4: Controlador de Codec de Audio para una FPGA

4

La entidad output_frame, como se menciona anteriormente, es la encargada de

generar las tramas, que luego son serializadas antes de mandarlas al códec.

Dado que la trama se forma mediante información relativa al volumen y

frecuencia del tono que se quiere transmitir al códec, dentro de esta entidad

también se generan las muestras del tono a transmitir, además de su

frecuencia y volumen.

Como extra, y para realizar un mejor diseño, se expande el control del volumen

y frecuencia a una entidad, en lugar de unos switches de la FPGA. Se pretende

realizar lo que se hacia con 8 switches, ahora con 2 botones y 1 switch. Para

ello se incluye vol_freq_control, que estará formada por una máquina de

estados y unos contadores.

Todas estas entidades en conjunto van a realizar el control del códec de audio

LM4550. Para cada entidad primero se va a proceder a realizar su traducción a

componentes electrónicos en base a su funcionalidad. Y luego serán re-

traducidos a código VHDL sintetizable. Cada entidad será verificada con

simulaciones en bancos de prueba, inyectando distintos estímulos.

1.- Detector de flanco de subida y de bajada configurable.

Para llevar a cabo el diseño en VHDL de esta entidad, primero se ha realizado

el diseño equivalente utilizando componentes electrónicos mostrados en la

figura 1.1.

Fig. 1.1 Esquemático del circuito

Page 5: Controlador de Codec de Audio para una FPGA

5

El diseño se detalla en los siguientes pasos:

1. La señal de entrada sobre la cual se quiere detectar los flancos

(input_signal se registra mediante un biestable, añadiendo éste

una latencia de un ciclo de reloj (10 ns) a la señal de salida

(din_r).

2. Al conmutar la señal input_signal, una de las puertas AND recibe

en una de sus entradas el valor de la señal actual (input_signal) y

en su otra entrada el valor de la señal de entrada registrada (not

(din_r)). En la otra puerta AND, ocurre lo contrario, un terminal

tiene not (input_signal), y el otro tiene din_r sin invertir.

3. De esta manera, al haber un flanco de subida en input_signal, el

valor anterior de esta señal es 0 (el cual se invierte en AND1), y el

actual es 1, por tanto r_edge detecta el flanco de subida con un

nivel alto, mientras que si hay un flanco de bajada, el valor

anterior de la señal es 1 y el actual es 0 (el cual se invierte en

AND2), y entonces f_edge detecta un flanco de bajada con

también con un nivel alto.

4. Las señales f_edge y r_edge se conectan a un multiplexor 2:1 en

el cual se selecciona mediante la señal mode la entrada que se

quiere transmitir al biestable de salida.

5. Por último, se registra la señal O_edge en el bistable de salida y

se obtiene edge_output, que estará activa durante un ciclo de

reloj.

Se visualiza mejor el comportamiento de Las puertas AND en la tabla 1.1,

descrita para cuando ocurre un flanco en la señal de entrada:

Señal Valor Valor

input_signal 0 1

din_r 1 0

r_edge 0 1

f_edge 1 0

Tabla1.1

Page 6: Controlador de Codec de Audio para una FPGA

6

Para la realización del diseño se han utilizado los componentes especificados

en la tabla 1.2:

Componente Número

Biestable 2

Puerta AND 2

Multiplexor 1

Inversor 2

Tabla 1.2 Componentes usados

Luego se procede a su simulación funcional para verificar su correcto

funcionamiento a través del análisis del cronograma mostrado a continuación.

Figura 1.3 Simulación funcional del detector de flancos

En la simulación se pueden observar dos señales internas en colores distintos

para la mejor comprensión de lo que está pasando. En azul se puede ver la

señal de entrada registrada, con su respectiva latencia (entre 0 y 10 ns

dependiendo de qué tan lejos estaba la señal de entrada al conmutar del flanco

de reloj). Esta latencia se aprovecha para generar la señal edge, cuya duración

depende de la latencia que tuvo la señal registrada. Edge pasa por otro

biestable (el de salida), quién le otorga otra latencia respecto a la señal de

entrada, pero estabiliza su duración en alto, dejándola fija en 10 ns para

cualquier tiempo en alto de edge. Esto evita posibles glitches y por eso siempre

es recomendable utilizar biestables de salida.

Page 7: Controlador de Codec de Audio para una FPGA

7

Para los estímulos se ha utiliza una señal de entrada que imita a la señal

bit_clk generada por el códec, como se puede apreciar en la figura 1.4.

Figura 1.4

Adicionalmente a eso, se genera una señal de clk de 100MHz, y se simula un

rst inicial de 32 ns. Finalmente para comprobar que el diseño puede detectar

flancos tanto de subida como de bajada, a la mitad de la simulación se procede

a cambiar “mode” de ‘1’ a ‘0’. En el cronograma se puede apreciar que al

cambiar mode, la señal de salida empieza a activarse para flancos de bajada

en lugar de subida.

En funcionamiento continuo el cronograma se vería como en la figura 1.5.

Figura 1.5 Vista alejada de la simulación.

Page 8: Controlador de Codec de Audio para una FPGA

8

En la vista alejada se puede apreciar mejor la variación de latencia de la señal

‘edge’, en contraste con la señal ‘edge_output’ que siempre está en alto 10ns.

Una vez verificado su compartamiento se procede a realizar la simulación

temporal.

Figura 1.6 Simulación temporal vista alejada

Aquí todo es bastante parecido a lo anterior, con la diferencia que el primer

flanco parece erróneo, como si de un flanco de bajada se tratase. Pero la

verdad, si se observa din_r_37, se aprecia que está detectando un flanco de

subida, lo que pasa es que din_r_37 tuvo un delay inexplicable al registrar la

señal de entrada. Para todos los siguientes flancos se puede ver que esta

anormalidad no continua.

Figura 1.7 Simulación temporal vista con zoom.

Para el comportamiento normal, todo es muy similar a la simulación funcional.

Page 9: Controlador de Codec de Audio para una FPGA

9

Una vez verificado el modelo vhdl, se adapta ligeramente para poder utilizarlo

en la construcción del detector doble de flancos. La señal mode pasa a ser un

genérico en lugar de un puerto. Todo lo demás sigue igual.

2.- Doble detector de flanco de subida y de bajada basado en un

modelo genérico.

Para este modelo, el componente doble_edge_detector está formado por la

instantación del componente creado previamente, el detector de flanco

edge_detector_generic.

Sin embargo, se instancia dos veces, una para detectar el flanco de subida

cuando “mode” vale ‘1’, y otra para que detecte el flanco de bajada cuando

“mode” vale ‘0’. Su funcionalidad es la misma que la estudiada en el punto 1.

Figura 2.1 Simulación funcional vista en funcionamiento continuo.

Ahora tenemos dos señales, una que detecta flancos solo de subida, y otra que

detecta flancos solo de bajada con sus latencias correspondientes.

Figura 2.2 Simulación funcional vista de cerca.

Como todo es igual que en el apartado anterior, se han omitido las señales

internas que se estudiaron para ese caso.

Page 10: Controlador de Codec de Audio para una FPGA

10

Figura 2.3 Estimulos del testbench.

Dado que este diseño no tiene señal mode, no ha sido necesario ponerla como

parte de los estímulos. Todo lo demás es idéntico.

Figura 2.4 Simulación temporal.

Otra vez a la hora de hacer la simulación temporal, ocurre algo anómalo, el

octavo flanco de bajada es inexistente. La causa de esto se desconoce.

Figura 2.4 simulación temporal de cerca.

En funcionamiento normal es igual al detector simple.

Page 11: Controlador de Codec de Audio para una FPGA

11

3.- Reset and sync generation. En esta ocasión se hará uso de más componentes. Dado que se tiene que

contar pulsos para generar la señal sync, se hará uso de un contador de 8 bits

sincronizado con r_edge_b_clk en su clock enable, para que vaya contado bits.

Para saber cuándo se ha alcanzado el nivel de cuenta deseado se utiliza un

comparador. Normal si se quisiera contar 16 pulsos, se haría de 0 a 15, pero

dado que sync debe iniciar su nivel alto cuando la cuenta es 255, se procede a

contar de 255 a 14, teniendo la cuenta iniciada en 255 después del rst inicial. Si

el valor de cuenta es 255, o cualquier número del 0 al 14, sync es ‘1’. Para

todos los demás valores de cuenta sync será ‘0’.

Por otro lado, la generación de un reset de 5 us implica contar tiempo, lo que

va a llevar a otro contador. El tiempo de una cuenta funcionando a frecuencia

de reloj es 10 ns por cuenta, entonces se necesitan 500 cuentas para llegar a

5000 ns = 5 us. Se procede a contar de 0 a 499 (en la práctica se ha puesto

500, por lo que se tiene 5010 ns de reset, pero se ha dejado así dado que

están todas las capturas hechas con ese valor). Y comparar de la misma forma

que se hacía con sync (con un comparador). Si la cuenta es menor de 500 la

salida del comparador es ‘0’, y si es mayor o igual la salida es ‘1’. Para que el

contador no siga contando se utiliza la propia salida del comparador como

clock enable del contador, solo que invertida. De esta manera después del

reset inicial, la cuenta es ‘0’, la salida del comparador es ‘0’, el clock enable es

‘1’. Y cuando el comparador pasa a ‘1’ el clock enable se desactiva a ‘0’ y

nunca más vuelve a activarse. Para contar hasta 500 se necesita un contador

de 9 bits.

Ambas salidas, sync y reset, se registran con biestables de salida para evitar

glitches, y se controla sus clock enable con la propia señal de salida de reset.

El valor de cuenta de bits también se conecta a una salida, pasando por un

biestable. Todo lo descrito se puede comprobar en el siguiente esquema.

Page 12: Controlador de Codec de Audio para una FPGA

12

Figura 3.1 Esquema de componentes de esta entidad. **Nota: En el diseño original el contador de 9 bits no tenia clock

enable, y se controlaba su periocidad con un multiplexor, tras implementar el clock enable como mejor solución, el mux

no fue removido, y ahora no fue removido por falta de tiempo, pero su comportamiento al ser redundante no afecta la

funcionalidad del sistema, solamente usa más lógica.

Figura 3.2 Simulación funcional de la entidad.

En esta captura se ve mejor la temporización de sync, el pequeño tiempo en

alto seguido de un tiempo en bajo mucho más largo.

Page 13: Controlador de Codec de Audio para una FPGA

13

Figura 3.3 Simulación funcional con énfasis en tiempo en alto de sync.

En este zoom se aprecia que sync se activa cuando la cuenta es 255 (FF), y

finaliza cuando es 14 (0E). Tambien se puede ver que el tiempo total de esto

es 1.31 us, lo cual es bastante aceptable con lo que debería dar (1.3 us).

Figura 3.4 Simulación funcional para visualizar tiempo en bajo de sync.

En esta otra captura están presentes dos markers que nos dicen que el tiempo

en bajo de sync ha sido de 19,53 us (también aceptable, dado que debería dar

cercano a 19,5 us).

Page 14: Controlador de Codec de Audio para una FPGA

14

Figura 3.5 simulación funcional, verificación de r_edge_b_clk.

Dado que se ha simulado la entidad de rst_and_sync_generation en un

testbench conjuntamente con la entidad double_edge_detector, se aprovecha

para verificar que el tiempo en alto es de 10 ns.

Figura 3.6 Estímulos para testbench.

Para este banco de pruebas no hubo ningún estímulo extraordinario.

Page 15: Controlador de Codec de Audio para una FPGA

15

Figura 3.7 Simulación temporal.

La simulación temporal desde esta vista se ve exactamente igual que la antes.

Figura 3.8 Simulación temporal zoom en sync.

Pero aunque no lo pareciera, hay una diferencia, ahora el tiempo en alto de la

señal sync es exactamente 1.3 us.

Figura 3.9 Simulación temporal zoom en sync 2.

Y se siguen respedando los valores de cuenta para los cuales sync debe

activarse.

Figura 3.10 Simulación temporal zoom en sync bajo.

Page 16: Controlador de Codec de Audio para una FPGA

16

Para la simulación temporal el tiempo en bajo es de 19.54 us, ligeramente

distinto a la simulación funcional.

4.- Output Frame Esta entidad es la entidad más importante del diseño, ya que es la encargada

de configurar y serializar la trama que se envía al códec, y se controla además

la frecuencia y volumen del tono a transmitir. Ya que se tiene que configurar 4

slots diferentes, la trama no es la misma para cada slot, y para modificar las

partes que cambian de la trama se hara uso de una máquina de estados. Esta

máquina tendrá 4 estados: initial, general, pcm, mastervol.

Figura 4.1 Máquina de estados que controla los slots 1 y 2 de la trama.

Cada estado, salvo el inicial, va a configurar un registro distinto en el códec. En

el slot 1 se manda la dirección de estos registros, y corresponde a ADR en el

Page 17: Controlador de Codec de Audio para una FPGA

17

esquema, y el slot 2 se mandan los datos a escribir en esos registros, y

corresponde con DATA.

En el slot 0 se manda el tag, que sirve para indicar qué registros vamos a usar

del códec y que información de manda de los canales de audio. El tag es el

mismo siempre en todas las tramas, y por tanto no forma parte de la máquina

de estados. Los slots 3 y 4 son para los datos de los canales de audio, en esta

práctica se ha optado por mandar la misma información por ambos canales.

Cada slot es para un canal.

Una vez que se tiene la trama, para evitar glitches nuevamente, la registramos,

y luego se procede a serializarla mediante un multiplexor de 256 entradas. Se

conecta dada bit de la trama a un canal del multiplexor, y se utiliza un contador

de 8 bits para ir cambiando de canal en canal, cosa de que en la señal única de

salida se obtienen los distintos bits. El contador de 8 bits está sincronizado con

r_edge_b_clk por su puesto, ya que estamos contando bits.

Adicional a esto, en esta entidad existe un control de frecuencia del tono que

se pretende enviar, actuando sobre el contador que barre la memoria que

contiene las muestras de los valores de un seno. Para actuar sobre el contador

se utiliza un prescaler controlado por un codificador que a su vez está

controlado por freq_code, el valor que se desea de frecuencia. Ya que

freq_code es un std_logic_vecto de 4 bits, se tienen 16 posibles frecuencias a

seleccionar, y se desea que se correspondan con los valores mostrados en la

siguiente tabla:

Frecuencia(Hz) Frecuencia primaria

Valor decimal Valor Hexadecimal

99,6 24414 245 F5

198,5 24414 122 7A

297,7 24414 82 52

393,8 24414 61 3D

498,2 24414 49 31

697,5 24414 35 23

976,6 24414 24 18

1220,7 24414 20 14

Page 18: Controlador de Codec de Audio para una FPGA

18

Si se barre la memoria a frecuencia de reloj (100MHz) el periodo del seno

resultante es de 24414KHz. Para seleccionar las frecuencias mostradas a la

izquierda de la tabla, se utiliza un prescaler con división ajustable mediante el

código freq_code. Se muestra tanto el valor decimal del entero que toma el

divisor del prescaler, como el valor en hexadecimal que tomaría freq_code para

las distintas frecuencias.

Este convertidor se puede fabricar con un simple case, y el prescaler es igual al

hecho en tutorial.

Figura 4.2 Esquema de la entidad.

1627,6 24414 15 0F

1878 24414 13 0D

2441,4 24414 10 0A

3000 24414 8 08

3487,7 24414 7 07

4069 24414 6 06

4882,8 24414 5 05

6103,5 24414 4 04

Page 19: Controlador de Codec de Audio para una FPGA

19

Todo lo explicado se resume en este esquema de bloques. Solo está en

ausencia el clock enable del registro de salida de sdata_out, que corresponde

con r_edge_b_clk.

Figura 4.3 Simulación temporal vista de lejos.

En esta visión general se puede ver que todo pareciera funcionar

correctamente, se observa un pico concentrado de bits en cada sync, lo cual

corresponde con el tag (xF800) que son 5 bits a 1 seguidos.

Figura 4.4 Simulación temporal. Visto más de cerca se aprecia mejor la serialización.

Figura 4.5 Simulación funcional con señales internas.

Para entender mejor lo que está pasando se agregan señales internas a la

simulación. Las señales ‘state’ y ‘clkdiv’ no se pudieron poner el color pero

alguna razón, pero también son señales internas.

Page 20: Controlador de Codec de Audio para una FPGA

20

Se puede ver que con cada sync, cambia el estado, lo cual es correcto, y

también se puede apreciar que cuando cambiamos el valor de frecuencia (los 4

ultimos bits de SW) a la máxima frecuencia, el prescaler empieza a activarse

mucho más seguido, y con ello, la memoria se barre mucho más rápido. Por lo

que se comprueba que el control de frecuencia funciona sin problemas.

Figura 4.6 Simulacíon funcional con zoom en el cambio de frecuencia.

Figura 4.7

Para este testbench aparte de los estímulos normales se ha hecho un barrido

de los SW, cambiando primero el valor del volumen y luego el valor de

frecuencia, para terminar cambiando los dos.

Cabe destacar que en esta simulación se ha simulado la entidad códec

controller, por recomendación del profesor, en lugar de simular output_frame

Page 21: Controlador de Codec de Audio para una FPGA

21

por sí solo. Así que todas las capturas correspondes a simulaciones del códec

controller.

5 y 6.- Control de Volúmen y Frecuencia, y modelo general final. Para mejorar el control de volumen y frecuencia (utilizar mejor pines de la

FPGA para su control) se ha propuesto un modelo vhdl que se va a situar en el

top system (recomendación del profesor).

Figura 5.1 Esquema de vol_freq_control.

Este módulo principalmente consta de 2 prescalers, 2 contadores, y una

máquina de estados.

Los prescalers se encargan de contador de 1 segundo en 1 segundo siempre y

cuando se mantenga presionado ya sea el botón de aumentar o de

decrementar (frecuencia o volumen).

Los contadores se encargan de aumentar o decrementar según las señales de

salida de la máquina de estados. No son contadores cíclicos, por lo que se

saturan al llegar a máxima/mínima cuenta. El valor de la cuenta es el valor de

los códigos de frecuencia o volumen.

Page 22: Controlador de Codec de Audio para una FPGA

22

La máquina de estados se encarga de decidir si los contadores son crecientes

o decrecientes según la combinación de botones que se presiona.

Figura 5.2 Grafo de la máquina de estados

Figura 5.3 Simulación funcional de top system incluyendo vol_freq_control.

Page 23: Controlador de Codec de Audio para una FPGA

23

Para apreciar lo que pasa con vol_code y freq_code, por recomendación del

profesor se han puesto en “leds” la concatenación de vol_code y freq_code.

Luego se ha procedido a estimular los botones de la FPGA primero ascendente

en frecuencia, luego descendente en frecuencia, después ascendente en

volumen, y finalmente descendente en volumen. Todos hasta saturación antes

de pasar a otro.

Figura 5.4 Estimulos para los botones y switches

Figura 5.5 Simulación funcional vista de cerca.

Más de cerca se observa como conmuta la memoria mñas lentamente de 485 a

486. Y como el canal derecho va siguiendo los valores de la memoria

Page 24: Controlador de Codec de Audio para una FPGA

24

correctamente. Tambien se observan datos aparentemente correctamente

serializados en sdata_out.

Figura 5.6 Simulación temporal de lejos.

Figura 5.7 Simulación temporal de cerca.

Las simulaciones temporales no salen igual pero pareciera que todo funciona.

No se pueden ver tan bien como las otras ya que es difícil encontrar las

señales internas en simulación temporal.

La cantidad de lógica inferida en este modelo descargable en placa es la

siguiente:

Page 25: Controlador de Codec de Audio para una FPGA

25

Page 26: Controlador de Codec de Audio para una FPGA

26

Y para el modelo del apartado 4 la lógica utilizada fue:

Page 27: Controlador de Codec de Audio para una FPGA

27

7.- Conclusiones En todo proyecto es clave tener las entidades claras y bien ordenadas para la

fácil comprensión y debug de errores. Tambien es importante ir haciendo las

simulaciones paso a paso, tanto las funcionales como las temporales, que son

muy importantes para ir verificando el funcionamiento del código.

Tambien es importante ir probando distintos estímulos en el banco de pruebas,

y a su vez ir verificando distintas señales internas, a veces el modelo parece

correcto pero el error yace en ellas.