Estoy tratando de comenzar con DSP en mi placa Spartan-3. Hice una placa AC97 con un chip de una placa base antigua, y hasta ahora pude hacer ADC, multiplicar las muestras por un número <1 (disminuir el volumen) y luego DAC.
Ahora me gustaría hacer algunas cosas básicas de DSP, como un filtro de paso bajo, paso alto, etc. Pero estoy realmente confundido acerca de la representación numérica (enteros? Punto fijo? Q0.15? ¿Desbordamiento o saturación?).
Solo quiero un código de ejemplo de un filtro simple real para comenzar. No es de alta eficiencia, rápido, ni nada de eso. Solo el filtro teórico implementado en VHDL.
He estado buscando, pero acabo de encontrar fórmulas teóricas: entiendo que lo que no entiendo es cómo procesar las muestras de audio de 16 bits y 48 kHz firmadas que obtengo del ADC. He estado usando estas bibliotecas: http://www.vhdl.org/fphdl/ . Si multiplico mis muestras por 0.5, 0.25, etc., puedo escuchar la diferencia. Pero un filtro más grande me da solo ruido.
Gracias.
Respuestas:
Parece que primero necesita descubrir los aspectos de DSP y luego realizar una implementación en FPGA.
En cuanto a los tipos de datos, puede usar enteros muy bien.
Aquí hay un código de muestra para que pueda comenzar. Tenga en cuenta que le faltan muchos problemas del mundo real (por ejemplo, reinicio, gestión de desbordamiento), pero con suerte es instructivo:
fuente
El filtro FIR de paso bajo más simple que puede probar es y (n) = x (n) + x (n-1). Puede implementar esto con bastante facilidad en VHDL. A continuación se muestra un diagrama de bloques muy simple del hardware que desea implementar.
De acuerdo con la fórmula, necesita las muestras ADC actuales y anteriores para obtener la salida adecuada. Lo que debe hacer es bloquear las muestras de ADC entrantes en el flanco descendente del reloj y realizar los cálculos adecuados en el flanco ascendente para obtener la salida adecuada. Como está agregando dos valores de 16 bits juntos, es posible que termine con una respuesta de 17 bits. Debe almacenar la entrada en registros de 17 bits y usar un sumador de 17 bits. Su salida, sin embargo, serán los 16 bits más bajos de la respuesta. El código puede verse así, pero no puedo garantizar que funcione por completo, ya que no lo he probado, y mucho menos sintetizado.
Como puede ver, puede usar esta idea general para agregar fórmulas más complicadas, como las que tienen coeficientes. Las fórmulas más complicadas, como los filtros IIR, pueden requerir el uso de variables para obtener la lógica del algoritmo correcta. Finalmente, una manera fácil de sortear los filtros que tienen números reales como coeficientes es encontrar un factor de escala para que todos los números terminen tan cerca de los números enteros como sea posible. Su resultado final deberá reducirse por el mismo factor para obtener el resultado correcto.
Espero que esto pueda serle útil y ayudarlo a poner en marcha la pelota.
* Esto se ha editado para que el enganche de datos y el enganche de salida se encuentren en procesos separados. También se utilizan tipos con signo en lugar de std_logic_vector. Supongo que su entrada de ADC será una señal std_logic_vector.
fuente
Otro fragmento de código simple (solo las tripas). Tenga en cuenta que no escribí el VHDL directamente, usé MyHDL para generar el VHDL.
Esta es una implementación directa. Requerirá multiplicadores. La síntesis de este circuito, dirigido a un Altera Cyclone III, no utilizó ningún multiplicador explícito, pero requirió 350 elementos lógicos.
Este es un filtro FIR pequeño y tendrá la siguiente respuesta (no tan bueno) pero debería ser útil como ejemplo.
Además, tengo un par de ejemplos, aquí y aquí , que pueden ser útiles.
Además, su pregunta parece preguntar: "¿qué es la representación apropiada de punto fijo?" Con frecuencia al implementar funciones DSP, se utiliza la representación de punto fijo, ya que simplifica el análisis de los filtros. Como se mencionó, el punto fijo es un entero artimético. La implementación real es simplemente trabajar con números enteros, pero nuestra representación recibida es fraccional.
Por lo general, surgen problemas al convertir de entero de implementación (punto fijo) a / de punto flotante de diseño.
No sé qué tan bien se admiten los tipos de punto fijo y de punto flotante VHDL. Funcionarán bien en la simulación, pero no sé si sintetizarán con la mayoría de las herramientas de síntesis. Creé una pregunta separada para esto.
fuente
OpenCores tiene varios ejemplos de DSP, IIR y FIR, incluido BiQuad. Tendrás que registrarte para descargar los archivos.
editar
Entiendo el comentario de Kortuk sobre enlaces muertos, y de hecho, si el enlace a OpenCores muere, la respuesta será inútil. Estoy bastante seguro de que esto no sucederá; mi enlace es genérico, y solo morirá si desaparece el dominio completo de OpenCores.
Traté de buscar algunos ejemplos que pudiera usar para esta respuesta, pero son demasiado largos para ser representados aquí. Así que seguiré mi consejo de registrarme en el sitio usted mismo (tuve que mudarme a Nueva York, porque mi ciudad natal no fue aceptada) y echar un vistazo al código presentado allí.
fuente
He intentado implementar scripts para la implementación automática de filtros IIR, donde puede definir si el diseño debe ser lo más rápido posible (para que cada multiplicación se realice con un multiplicador dedicado) o lo más pequeño posible (para que cada multiplicador se reutilice).
Las fuentes se han publicado en alt.sources como "Implementación conductual pero sintetizable de filtros IIR en VHDL" (también puede encontrarla en el archivo de Google: https://groups.google.com/group/alt.sources/msg/c8cf038b9b8ceeec ? dmode = fuente )
Las publicaciones en alt.sources están en formato "shar", por lo que debe guardar el mensaje como texto y descomprimirlo (con la utilidad "unshar") para obtener las fuentes.
fuente
¿Qué tal esto? https://github.com/MauererM/VIIRF
Implementa un filtro IIR basado en biquad (SOS, secciones de segundo orden) que se encarga de la implementación de punto fijo. También presenta scripts Python para el diseño y verificación del filtro. No utiliza construcciones FPGA específicas del proveedor y puede elegir el equilibrio entre el uso de alta velocidad y bajo área.
fuente