¿Puede un diseño FPGA ser en su mayoría (o completamente) asíncrono?

Tuvimos un curso muy corto de FPGA/Verilog en la universidad (hace 5 años) y siempre usábamos relojes en todas partes.

Ahora estoy comenzando de nuevo con los FPGA como pasatiempo, y no puedo evitar preguntarme acerca de esos relojes. ¿Son absolutamente necesarios o un diseño basado en FPGA puede ser completamente asíncrono? ¿Se puede construir un conjunto complejo de lógica y hacer que las cosas fluyan a través de él lo más rápido posible?

Me doy cuenta de que hay muchas trampas con esto, como saber cuándo la señal se ha propagado a través de todas las partes del circuito y la salida se ha estabilizado. Eso no viene al caso. No es que quiera construir un diseño que sea completamente asincrónico, sino solo para mejorar mi comprensión de las capacidades.

Para mi ojo de principiante, parece que la única construcción que requiere absolutamente un reloj es un reg, y entiendo que un FPGA típico (digamos, un Cyclone II) tendrá sus flip-flops precableados para señales de reloj específicas. ¿Es esto correcto? ¿Hay otros relojes implícitos como este y normalmente pueden ser controlados manualmente por el diseño?

Sé que Simon Moore, de la Universidad de Cambridge, investigó mucho sobre el diseño asincrónico, incluida la fabricación de un chip de prueba. Requiere un conjunto completamente nuevo de herramientas de diseño y tiene efectos secundarios extraños: velocidad de ejecución inversamente proporcional a la temperatura, por ejemplo.

Respuestas (9)

Una respuesta corta sería: sí; una respuesta más larga sería: no vale la pena su tiempo.

Un FPGA en sí mismo puede ejecutar un diseño completamente asíncrono sin ningún problema. El resultado que obtiene es el problema, ya que el tiempo a través de cualquier FPGA no es muy predecible. El mayor problema es el hecho de que su tiempo y el diseño resultante variarán casi definitivamente entre diferentes lugares y sesiones de ruta. Puede imponer restricciones en rutas asíncronas individuales asegurándose de que no tomen demasiado tiempo, pero no estoy seguro de que pueda especificar un retraso mínimo.

Al final, significa que su diseño será impredecible y potencialmente completamente variable incluso con un ligero cambio de diseño. Tendría que revisar todo el informe de tiempo cada vez que cambie algo para asegurarse de que aún funciona. Por otro lado, si el diseño es síncrono, solo busca un paso o falla al final del lugar y la ruta (suponiendo que sus restricciones estén configuradas correctamente, lo que no toma mucho tiempo).

En la práctica, las personas apuntan a diseños completamente sincrónicos, pero si necesita simplemente almacenar en búfer o invertir una señal, no necesita pasar por un flip flop siempre que lo restrinja adecuadamente.

Espero que esto lo aclare un poco.

Tuve que usar algunos dispositivos con diseños FPGA asíncronos. Era difícil trabajar con ellos. Por favor, al menos use restricciones de tiempo
Si bien es cierto que es posible implementar diseños asincrónicos con un FPGA, la mayoría de los FPGA están diseñados para admitir diseños específicamente sincrónicos. Tienen muchos recursos (PLL, circuitos de distribución de reloj y una gran cantidad de flip-flops) que se desperdiciarán en un diseño asíncrono.
Esta respuesta no proporciona un consejo particularmente bueno. Puede crear un FPGA sin reloj y en realidad simplifica el lugar y la ruta, elimina una tonelada de problemas relacionados con los requisitos de tiempo y, debido a la canalización de grano fino, puede tener un rendimiento considerablemente mayor. El verdadero problema surge cuando intenta mapear un circuito con reloj a un FPGA sin reloj porque tienen características de tiempo muy diferentes. Se puede hacer, solo requiere un poco más de procesamiento de front-end para realizar la conversión. vlsi.cornell.edu/~rajit/ps/rc_overview.pdf
PUEDES hacer un diseño insensible a los retrasos. Diseñé un pequeño circuito que almacena un bit en un flip-flop y genera una señal cuando detecta que el bit ha sido almacenado. También detecta si el bit realmente se recibió (en lugar de aparecer como un cero debido a la demora en enviar un 1) y es inmune a fallas. Los circuitos tienen que comunicarse vía apretón de manos y usar este tipo de componentes para interactuar; los propios circuitos solo esperan a que se complete su salida y luego realizan todas las comunicaciones. sin reloj

"¿Se puede construir un conjunto complejo de lógica y hacer que las cosas fluyan a través de él lo más rápido posible?" Sí. Se han construido CPU completas que son completamente asincrónicas; al menos una de ellas era la CPU más rápida del mundo. http://en.wikipedia.org/wiki/Asynchronous_circuit#Asynchronous_CPU

Me molesta que la gente rechace las técnicas de diseño asíncrono, aunque teóricamente tienen varias ventajas sobre las técnicas de diseño síncrono, simplemente porque (como han dicho otros aquí) los diseños asíncronos no son tan compatibles con las herramientas disponibles.

Para mí, eso es como recomendar que todos los puentes estén hechos de madera, porque más personas tienen herramientas para trabajar la madera que herramientas para trabajar el acero.

Afortunadamente, algunas de las ventajas del diseño asíncrono se pueden obtener sin dejar de utilizar técnicas de diseño en su mayoría síncronas mediante el uso de un diseño síncrono local asíncrono global (GALS) .

Siento exactamente lo mismo acerca de la tendencia moderna de enrutar PCB en una cuadrícula cuadrada , aunque los beneficios de la migración son mucho menos significativos.
@romkyns: eso se debe más al hecho de que es difícil escribir software de PCB que use cuadrículas no rectilíneas .
Me topé con esta respuesta tuya a una pregunta anterior. GALS parece ser un término para los diseños que toman una serie de bloques síncronos y los interconectan aunque sean asíncronos entre sí. ¿Existe un término para los dispositivos que son cronometrados por diferentes relojes que tienen una relación de tiempo conocida (por ejemplo, el flanco ascendente del reloj X (X+) no será posterior al flanco ascendente de Y (Y+), y ocurrirá significativamente antes del flanco descendente de Y (Y-); X+ se puede usar para sincronizar datos derivados de datos sincronizados por Y+ pero no viceversa; Y- sincroniza datos derivados de X+).
@supercat: sospecho que te refieres a la lógica de cuatro fases . Es una de las señales de reloj multifase que parece estar olvidada.
No estaba pensando en la lógica dinámica. Simplemente estaba pensando en cómo garantizar relaciones causales adecuadas con señales de reloj que podrían estar ligeramente sesgadas. Si se obtiene un flanco ascendente del reloj n.º 2 al combinar el reloj n.º 1 con alguna otra lógica, de modo que ocurra después de un flanco ascendente del reloj n.º 1, usando un flanco ascendente del reloj n.º 1 para bloquear una señal que cambia en un el flanco ascendente del reloj #2 generaría una condición de carrera. Usar un flanco descendente del reloj n. ° 2 en su lugar debería ser seguro.
@supercat: Correcto. Tal vez esté pensando en sistemas con un reloj de dos fases o algún otro sistema de reloj multifásico. Avíseme si encuentra un término mejor para estos sistemas.
@davidcary: Más o menos, excepto ambas "fases" en un cable: una fase controlada por el flanco ascendente y otra por el flanco descendente. Básicamente, dividiría los relojes de cierre en cuatro categorías: aumento limpio, descenso limpio, aumento tardío, descenso tardío. Los pestillos sincronizados por (L/CB) un flanco ascendente o descendente limpio podrían tomar datos de cualquier flanco ascendente o descendente. L/CB un flanco de subida tardío podría tomar datos de L/CB limpiar el flanco de subida cualquier flanco de bajada. L/CB por flanco descendente tardío podría tomar datos de la caída limpia de L/CB o cualquier aumento.
@davidcary: Siempre que el tiempo de propagación más rápido para cualquier pestillo exceda el tiempo de espera más largo, y siempre que la ruta de señal más larga desde un borde de reloj, a través de la lógica de activación del reloj y los pestillos "tardíos" activados por ese borde, a cualquier pestillo activado por el siguiendo el borde, no excede el tiempo mínimo entre los bordes del reloj, creo que dicho diseño debería ser completamente confiable y libre de metaestabilidad generada internamente bajo cualquier combinación de retrasos de propagación.
@supercat: curiosamente, recientemente diseñé un procesador que usa este tipo de enfoque: tengo una sola entrada de reloj que ejecuta varias fases en orden (1) permite múltiples actualizaciones de registro por ciclo mientras uso un diseño de archivo de registro que solo tiene una entrada puerto y (2) tener una canalización de dos etapas completa desde la lectura de la instrucción hasta la reescritura del registro en 1,5 ciclos para que los peligros de la canalización solo duren una sola instrucción. Hay una descripción general aquí y una descripción más detallada aquí este hilo del foro .
Estoy trabajando en un diseño de PCB para él cuando encuentro tiempo (hasta ahora solo es simulado), pero estoy usando un inversor con una capacitancia agregada a su salida para proporcionar un ligero retraso en el reloj de escritura del archivo de registro en orden para dar tiempo a que todo lo demás termine antes de que se escriba el resultado. En la simulación todo se ve bien... veremos qué sucede cuando tenga una placa real para ello. :)
@Jules: Gracias. Ese diseño de CPU parece fascinante.

Un factor aún no mencionado es la metaestabilidad. Si un circuito de enganche recibe una secuencia de entradas/transiciones tal que el estado resultante dependa de retrasos de propagación u otros factores impredecibles, no hay garantía de que el estado resultante sea un "alto" o "bajo" limpio. Considere, por ejemplo, un flip-flop activado por flanco que actualmente emite un "bajo" y su entrada cambia de bajo a alto casi al mismo tiempo que llega un flanco de reloj. Si el borde del reloj ocurre lo suficiente antes de que cambie la entrada, la salida simplemente se mantendrá baja hasta el próximo borde del reloj. Si el borde del reloj ocurre lo suficiente después del cambio de entrada, la salida cambiará rápidamente una vez de bajo a alto y permanecerá allí hasta el siguiente borde del reloj. Si no se cumple ninguna de esas condiciones,. Puede permanecer bajo, o cambiar rápidamente una vez y permanecer alto, pero puede permanecer bajo por un tiempo y luego cambiar, o cambiar y luego, algún tiempo después, volver, o cambiar de un lado a otro varias veces, etc.

Si un diseño es completamente síncrono y todas las entradas están doblemente sincronizadas, es muy poco probable que un pulso de temporización golpee el primer pestillo de un sincronizador de tal manera que haga que cambie en el momento perfecto para confundir al segundo. pestillo. En general, es seguro considerar tales cosas como "simplemente no sucederán". En un diseño asíncrono, sin embargo, a menudo es mucho más difícil razonar sobre tales cosas. Si se viola una restricción de tiempo en un circuito de bloqueo (no solo flip flops, sino cualquier combinación de lógica que actuaría como un bloqueo), no se sabe qué hará la salida hasta la próxima vez que haya una condición de entrada válida que fuerce el bloqueo. a un estado conocido. Es muy posible que las salidas retrasadas provoquen que se violen las restricciones de tiempo de las entradas aguas abajo, lo que provocará situaciones inesperadas,

La forma más segura de modelar un circuito asíncrono sería hacer que casi todos los circuitos de salida produzcan una salida "X" durante un tiempo cada vez que cambie entre "0" y "1". Desafortunadamente, este enfoque a menudo da como resultado que casi todos los nodos muestren "X", incluso en casos en los que en realidad casi con seguridad habrían resultado en un comportamiento estable. Si un sistema puede funcionar cuando se simula que todas las salidas se convierten en "X" inmediatamente después de que cambia una entrada, y permanece "X" hasta que las entradas sean estables, es una buena señal de que el circuito funcionará, pero hacer que los circuitos asíncronos funcionen bajo tales restricciones es a menudo difícil.

Realmente hay TRES tipos de diseños.

  1. Combinacional. No hay relojes ni rutas de retroalimentación y el sistema no tiene "memoria". Cuando una o más entradas cambian, los cambios se propagan a través de la lógica. Después de un tiempo, la salida se asienta en un nuevo estado donde permanece hasta que las entradas cambian nuevamente.
  2. Secuencial síncrono. Un sistema se construye a partir de registros y bloques de lógica combinatoria, los registros son cronometrados por un pequeño número (a menudo 1) de relojes. Si hay varios relojes, es posible que se necesiten precauciones especiales en las señales que pasan de un dominio de reloj a otro.
  3. Secuencial asíncrono. Hay caminos de retroalimentación, pestillos, registros u otros elementos que le dan al diseño memoria de eventos pasados ​​y que no son cronometrados por líneas de reloj fácilmente analizadas.

En general, al sintetizar/optimizar la lógica combinatoria, las herramientas asumirán que todo lo que importa es cuál es el resultado final y el tiempo máximo necesario para establecer ese resultado.

Puede construir un diseño que sea puramente combinatorio y obtendrá el resultado correcto. Las salidas pueden cambiar en cualquier orden y pueden cambiar varias veces antes de alcanzar sus valores finales. Dichos diseños son un gran desperdicio de recursos lógicos. La mayoría de los elementos lógicos pasarán la mayor parte de su tiempo inactivos, mientras que en un sistema secuencial podría haber reutilizado esos elementos para procesar múltiples elementos de datos.

En un sistema síncrono secuencial, todo lo que importa es que las salidas del bloque combinatorio se hayan establecido en su estado correcto cuando se sincronizan en el siguiente flip flop. No importa en qué orden cambien o si son fallas en el camino. Nuevamente, las herramientas pueden convertir fácilmente esto en una lógica que, siempre que el reloj sea lo suficientemente lento, dé la respuesta correcta (y pueden decirle si el reloj que desea usar es lo suficientemente lento).

En un sistema secuencial asíncrono, esas suposiciones desaparecen. Los fallos pueden ser importantes, el orden de los cambios de salida puede ser importante. Tanto las herramientas como los propios FPGA fueron diseñados para diseños síncronos. Ha habido mucha discusión (busque el diseño de FPGA asíncrono en Google si desea saber más) sobre la posibilidad de implementar sistemas asíncronos en FPGA estándar o en los diseñados específicamente, pero aún se encuentra fuera de la práctica de diseño aceptada.

Por supuesto, si sus requisitos de diseño son lo suficientemente lentos como para que muchos retrasos internos sigan siendo órdenes de magnitud más largos que los tiempos que le interesan, entonces no hay problema, y ​​puede consultar el informe de tiempo para controlar esto, pero hay un límite para lo que puede hacer de manera útil sin información de estado interno. Si solo desea hacer algo como un multiplexor de 100 entradas, está bien, solo recuerde que cada entrada tendrá un retraso de propagación diferente. De hecho, puede obtener algunos efectos interesantes y caóticos con una gran cantidad de bucles de retroalimentación oscilantes con retraso impredecible; tal vez un sintetizador basado en FPGA totalmente asíncrono podría ser el próximo 'analógico'.

Sí tu puedes. Puede ignorar los flip-flops por completo y construirlo todo a partir de LUT. Y/o puede usar los elementos de estado de la mayoría de los FPGA de Xilinx como pestillos (activados por nivel) en lugar de flip-flops (activados por borde).

Un peligro con eso es que, a menos que uno restrinja el compilador lógico, puede producir una lógica que tenga un tiempo de propagación negativo para algunas puertas. Por ejemplo, si uno especifica X=(someComplexFormula)y Y=X & D, y si el compilador sustituye esa fórmula por X y determina que X & Des equivalente a A & D, el compilador podría reemplazar el cálculo de Y en términos de A y D, en lugar de en términos de X, permitiendo así el cálculo de Y para proceder más rápido que el de X. Tales sustituciones son válidas con la lógica combinatoria, pero causan estragos en la lógica secuencial asíncrona.
@supercat: nunca trabajé con las herramientas de Xilinx, pero cuando trabajé con Altera FPGA, siempre tuvo la opción de especificar cualquier ruta crítica como módulos de puerta conectados en lugar de en RTL, momento en el cual tales optimizaciones son discapacitado.
@Jules: Todos mis diseños de lógica programable han usado Abel, que es un lenguaje un tanto tonto, pero permite especificar cosas de formas que algunos CPLD pueden implementar, pero que pueden plantear dificultades para una herramienta de síntesis VHDL o Verilog. Por ejemplo, en uno de mis proyectos, aproveché el hecho de que las piezas de Xilinx tienen reloj, configuración asíncrona y reinicio asíncrono para implementar un registro de desplazamiento cargable asíncrono. Si necesito hacer tales cosas en un FPGA, sin haber usado nunca Verilog o VHDL, ¿cómo debo aprender lo que se necesita para hacerlo? Por cierto, si la memoria no me falla, usé T flops para la palanca de cambios, y...
... el tiempo era tal que la escritura asíncrona solo podía ocurrir en momentos en que la entrada T sería baja, suponiendo que si ocurriera un nop-clock cerca del comienzo de un pulso de escritura, la escritura asíncrona se extendería lo suficiente más allá como para garantizar un valor estable, y si el reloj nop se produjera cerca del final, simplemente estaría bloqueando un valor aún estable. No estoy seguro de cómo se podrían manejar estos casos de manera eficiente en VHDL o Verilog.
@supercat: tomando un problema similar, mirando el Manual del dispositivo Cyclone IV, veo que el mejor enfoque para el mismo problema sería usar la opción "Carga síncrona en todo el LAB" (un "LAB" es un grupo de 16 elementos lógicos , por lo que si el tamaño de dicho registro no termina siendo un múltiplo de 16 bits, se desperdiciarán algunos bits, pero esta parece ser la opción más útil de todos modos). Ahora tengo dos opciones: puedo escribir verilog funcional que requerirá que la herramienta de síntesis elija una forma de implementar el registro requerido (que generalmente sería la mejor opción) o, si tengo un tiempo estricto...
... requisitos Puedo obligarlo a cablear esto: mirar a través de la lista de módulos de bajo nivel disponibles en el dispositivo que encuentro lpm_ffpuede implementar un flip flop tipo d o t con carga síncrona. Al usar este módulo, puedo estar seguro de que estas funciones se asignarán exactamente a las características de bajo nivel del dispositivo sin la posibilidad de que estén optimizadas.

Como señaló @Andrey, no vale la pena su tiempo. Específicamente, las herramientas no hacen esto, por lo que estaría completamente solo. Además, dado que tienen registros incorporados, no ahorraría nada al no usarlos.

Sí. Si no tiene construcciones de tipo de proceso, entonces no debería hacer cosas como inferir registros. Habrá cosas como la memoria integrada que requieren relojes, aunque si realmente lo desea, probablemente podría generarlos de forma asíncrona.

¿Querías hacer de esto una respuesta única?

FWIW Pensé que debería agregar que un objetivo obvio en las soluciones de lógica asíncrona sería la reducción global en el consumo de energía.

Esos relojes/PLL/búferes globales queman muchos julios.

A medida que las soluciones FPGA serpentean en arenas alimentadas por baterías (por ejemplo, Lattice Icestick), este aspecto adquirirá mucha más atención.

Este es un buen punto, aunque vale la pena considerar que un circuito combinatorio mal diseñado que realiza la misma operación que un circuito secuencial podría, en algunos casos, generar muchas transiciones transitorias a medida que se calculan los resultados parciales y la salida final se actualiza para tenerlos en cuenta. y en los circuitos CMOS (como lo son la mayoría de los FPGA) el consumo de energía es aproximadamente proporcional al número de transiciones. Los relojes pueden causar transiciones innecesarias, pero también puede hacer muchas reducciones de potencia desactivando los relojes en partes del circuito que no se necesitan en este momento.