Estoy aprendiendo a usar un FPGA (placa de desarrollo de Papilio, que tiene un xilinx spartan3e, usando vhdl).
Necesito dividir un pulso entrante por un número (codificado).
Puedo ver 3 opciones, aproximadamente, como pseudocódigo (usando 10 cuentas como ejemplo):
- Inicialice a 0, en el flanco ascendente de entrada aumente en 1, compare con 10; si son iguales, restablezca a 0 y active el pulso de salida
- Inicialice a 10, en el borde ascendente de entrada disminuya en 1, compare con 0; si son iguales, restablezca a 10 y active el pulso de salida
- Inicialice a 9, pero asegúrese de que haya al menos 1 bit "0" inicial, que es mi bit de salida. En el flanco ascendente de entrada, disminuya en 1. En el flanco ascendente del bit de salida, reinicie.
El ciclo de trabajo no es importante.
¿Es uno de estos mejor que los otros? ¿Existe un método aún mejor en el que no haya pensado?
¿Existe una forma "estándar" que le dará al compilador la mejor oportunidad de optimización?
Respuestas:
Optimizar a este nivel te romperá el corazón. El resultado podría cambiar debido a la tecnología del FPGA que está utilizando, otros factores en el FPGA, pero también debido a factores fuera de su control, incluida la semilla de números aleatorios del instalador.
Dicho esto, creo que la opción 3 será la mejor. Las opciones 1 y 2 tienen una puerta de comparación / OR que va entre los contadores para que pueda indicar que se ha alcanzado el número objetivo. La opción 2 puede ser un poco más rápida que la 1, ya que todo puede ser OR recto sin ningún inversor, pero nuevamente se encuentra con pequeñas diferencias tecnológicas en las que puede ser más rápido a AND o XOR.
La opción 3 omite la comparación por el bajo costo de un bit extra en el contador. Esto debería valer la pena, a menos que esté severamente restringido en chanclas.
Un hecho divertido acerca de los contadores es que tienden a agruparse en un tamaño específico del dispositivo dentro de un bloque lógico, y verá que el tiempo cambia más de lo esperado si este bit adicional lo empuja fuera de ese grupo.
fuente
Otra opción sería inicializar el contador a 6 (= 2 4 - 10), contar y luego restablecer cuando se activa la salida de acarreo (es decir, los FF son todos unos).
La ventaja de esto es que no requiere un FF adicional, y muchos FGPA tienen una lógica auxiliar dedicada para acelerar este tipo de operación de transporte en un circuito contador o sumador.
fuente
Depende Por ejemplo: el retraso de propagación del flip-flop para 0 → 1 y 1 → 0 puede ser diferente y, por lo tanto, los retrasos de transición de un contador para 000 → 001 y 001 → 000 pueden ser ligeramente diferentes. Puede ser mayor o menor, dependiendo de la tecnología CMOS utilizada en FPGA. Por lo tanto, debe sintetizar y descubrir cuál tiene un mejor rendimiento de sincronización.
fuente
Desde la perspectiva de un escritor del compilador: si utiliza
integer
, la representación interna no está definida, y el compilador es libre de elegir la implementación más eficiente.Si fuerza una representación interna particular, el optimizador aún intentará mejorarla, pero comenzará desde un punto de vista ligeramente peor.
A menos que conozca la estructura interna, los recursos asignados a otra lógica (muchos FPGA tienen lógica de punto flotante múltiple de suma dedicada que también puede usar para implementar un contador si tiene unidades sobrantes) y están completamente seguros de que no cambiará para un modelo diferente, la respuesta es "no lo pienses".
fuente