VHDL

Metrónomo en VHDL (1 de 3): ¿Es siquiera posible?

Metrónomo [(cc)(by)(sa) Paco Vila]

Hace ya tiempo, Felipe expresó su inquietud en un comentario: estaba interesado en la creación de un metrónomo con VHDL. Esta serie de entradas son gracias a él.

Antes que nada, es necesario decir que un metrónomo es un instrumento preciso y debe marcar el tiempo con el menor error posible. Tras esta breve descripción surge la necesidad de analizar si un metrónomo hecho con divisores de frecuencia en base a contadores es o no posible.

Pero, ¿por qué no sería posible? Esto se debe a que existen frecuencias para las cuales el contador que determina la frecuencia exacta es un número fraccionario y, debido al redondeo que se debe hacer para implementar el contador, existe un pequeño error entre la frecuencia de salida esperada y la frecuencia de salida obtenida. Suficiente plática, mejor vamos a los números.

Un poco de matemáticas

Veamos un pequeño ejemplo para ver qué tanta diferencia puede existir, ya que los números generalmente no mienten. Asumamos que tenemos un reloj de entrada de 50MHz, y deseamos una salida de 295 Hz. Según aprendimos en divisor de frecuencia con VHDL, el factor de escalamiento está dado por:

\( Escala = \dfrac{f_{entrada}}{f_{salida}} = \dfrac{50 MHz}{295 Hz} \approx 169491.525424 \)

Como el contador no puede utilizar la parte fraccionaria de 169491.525424, se debe elegir entre los dos números enteros más cercanos: 169491 o 169492. En este caso, el que genera menos diferencia respecto al valor esperado es 169492, por lo que se realiza el cálculo de la frecuencia de salida ajustada con el nuevo valor:

\( f_{salida} = \dfrac{f_{entrada}}{Escala} = \dfrac{50 MHz}{169492} \approx 294.999174 Hz \)

Viéndolo bien, no existe tanto problema. Es decir, tenemos 294.999174 Hz, ni siquiera cuenta como una diferencia, ¿por qué crear un conflicto tan grande por una pizca decimal? Aún asi, veamos qué tanto es dicho error con ayuda de la ecuación del error absoluto:

\( \mbox{Error absoluto} (e_{abs}) = \mbox{Valor real o esperado} – \mbox{Valor medido u obtenido} \)

Por lo que nuestro error absoluto es:

\( e_{abs} = 295 Hz – 294.999174 Hz = 826 \mu Hz \)

Ya estando calculando los errores, calculemos el error relativo porcentual:

\( \mbox{Error relativo porcentual} (e_{rel}) = \dfrac{\mbox{Error absoluto}}{\mbox{Valor real o esperado}} \times 100 \)

Lo que nos da un error relativo porcentual de

\( e_{rel} = \dfrac{826 \mu Hz}{295 Hz} \times 100 = 0.00028\% \)

Por lo que en teoría no tenemos ningún problema, ¿quién notaría un error del 0.00028%? ¡Prácticamente es nulo! No obstante, existe un pequeño problema: ese error existe en cada ciclo de reloj, cada iteración, cada flanco de subida arrastra un poco de ese error *gasp*.

Ahora bien, para un músico lo importante es conocer los tiempos, no las frecuencias. Así que no deseamos saber el error que existe en Hertz, queremos saber cuánto error existe hablando de tiempo, ¿tendremos retraso? ¿nos estaremos adelantando?

Para ello calculamos la diferencia de tiempo absoluta que existe entre la frecuencia esperada y la frecuencia obtenida (de momento, no interesa saber si nos retrasaremos o adelantaremos):

\( t_{diff} = \left| \dfrac{1}{f_{esperada}} – \dfrac{1}{f_{obtenida}} \right| = \left| \dfrac{1}{295 Hz} – \dfrac{1}{294.999174 Hz} \right| \approx 9.4915 ns \)

Así pues, cada ciclo de nuestro reloj de 294.999174Hz (o 3.3898 ms) estaremos desfasados un tiempo de 9.4915ns. Para saber cúanto tiempo estamos desfasados al transcurrir un segundo, realizamos una simple regla de tres:

\( t_{diff \times seg} = \dfrac{t_{nuevo} \times t_{diff}}{t_{obtenido}} = \dfrac{1s \times 9.4915 ns}{3.3898 ms} \approx 2.80 \mu s \)

Y para cada minuto, hora, y día:

\( t_{diff \times min} = \dfrac{60s \times 9.4915ns}{3.3898ms} \approx 168 \mu s \) \( t_{diff \times hr} = \dfrac{3600s \times 9.4915ns}{3.3898ms} \approx 10.08 ms \) \( t_{diff \times dia} = \dfrac{86400s \times 9.4915ns}{3.3898ms} \approx 241.92 ms \)

Después del análisis para este caso en particular, se concluye que una pérdida de 10.08ms por hora no es significativa y se puede continuar con el análisis para otros valores (espero los músicos no me odien por ese pequeño comentario). Ahora sólo debemos saber que no hay pérdidas significativas para ninguna frecuencia de todas las deseadas.

Espera, ¿aún hay que calcular ésto mismo para cada frecuencia?

Así es. Antes de comenzar el diseño del metrónomo en VHDL debemos estar completamente seguros que las pérdidas no son significativas para ninguna frecuencia. Según se define en Wikipedia, los pulsos por minuto pueden ir de 40 a 208. En otras aplicaciones como Metrónomo, para Android, se puede especificar las cantidad de BPM (pulsos por minuto) entre 1 y 300.

Para este proyecto se utilizará el rango de frecuencias equivalentes al rango entre 1 BPM y 300 BPM, lo que corresponde a 1/60Hz y 5Hz. Ahora es necesario mover el lápiz 300 veces para calcular 300 valores de contadores diferentes, así como su error por segundo, ¿listos?

¿Ya acabaron?

¿Al menos empezaron?

¡Bah! ¡Está bien! Como soy un chico muy bueno, cree un pequeño script que genera los datos necesarios (pero no se acostumbren):Cálculo de escalas para divisores de frecuencia, a ser ejecutado con los siguientes valores:

  • Frecuencia de entrada: 50000000 Hz (50 MHz)
  • Frecuencia mínima deseada de salida: 0.016666666667 Hz (1 BPM)
  • Frecuencia maxima deseada de salida: 5 Hz (300 BPM)
  • Incremento entre elementos: 0.016666666667 Hz (1 BPM)

En el script, favor de escribir solamente los números (se comporta extraño con las letras).

Tras ejecutar el script con los datos proporcionados, aparecerá la tabla con los 300 elementos. Antes de toda esa información, se muestra el error máximo del conjunto. Para nuestro caso, el error máximo es 9.81ns por ciclo, en el elemento 253. El error por minuto para el elemento es 2.48ms, lo cual sigue siendo un error muy bajo.

Parece que ya tenemos los cálculos, ¿ahora qué?

Ya con todos los valores reunidos en un solo lugar, ¿qué sigue? Un proyecto relacionado es el multiplexor de frecuencias, en el cual se tienen ocho frecuencias diferentes, y una sola salida (se parece a lo que deseamos hacer). Peeeero, en ese proyecto se creó cada uno de los divisores de frecuencia… y personalmente no pienso que crear 300 divisores de frecuencia diferentes y hacer un multiplexor 300 a 1 (me recuerda a la analogía entre multiplexor y la película de 300) sea una muy buena opción.

Así que finalmente será necesario sacar el conocimiento del baúl mágico y crear algo como “multiplexor de frecuencia variable”, lo cual consistirá en los datos de los contadores almacenados en una memoria, para posteriormente ser extraídos en base a la entrada de selección.

Ahora ya sabemos que el error no es mucho, y que un metrónomo con VHDL y divisores de frecuencia basados en contadores puede ser una realidad, es tiempo de poner nuestras manos a la obra…Este proyecto continuará en Metrónomo en VHDL (2 de 3): ¿Alguien dijo variable?, disponible el viernes 9 de mayo de 2014.

¿Qué hacemos mientras esperamos la segunda parte?

La verdad es que existen muchas formas de implementar un metrónomo con VHDL, o cualquier componente en general. Lo que tengo pensado es almacenar los contadores en una memoria y usar los datos según la selección. Otra solución puede ser simplemente muchos if o case.

Sin embargo, sigue siendo un componente en desarrollo y acepto sugerencias para la creación del código final. ¿Hay un código en la red para un metrónomo en VHDL? ¿tienen código como parte de sus prácticas de laboratorio? ¡Cualquier cosa puede servir!

Además, me gustaría saber cuáles son los FPGA con los que trabajan para posiblemente crear proyectos orientados a dichas arquitecturas. La sección de comentarios está abierta a sus sugerencias.

PD. Por cierto, ¿notaron acaso que el valor del ejemplo, 295Hz, no está siquiera dentro de los valores utilizados para el metrónomo? Esto se debe a que al estar redactando, estaba pensando en que 1BPM = 1Hz, ¡vaya error!

You Might Also Like

2 Comentarios

  • Responder
    Grecia
    mayo 7, 2014 at 11:30 am

    Alabado seas! Y no te preocupes, estoy segura de que por razones de cantidad de movimiento y conservación del centro de masa, los metrónomos mecánicos tienen un margen de error notablemente mayor… 🙂

    • Responder
      Carlos Ramos
      mayo 7, 2014 at 11:14 pm

      Gracias, Grecia.
      A decir verdad, no me di a la tarea de analizar el error que existe en los metrónomos mecánicos (o en los digitales que existen en páginas web y celulares). Deberé buscar ese numerito para futuras referencias, nunca está de más un conocimiento extra.
      Saludos.

    Deja tu comentario