Cómo obtener un diseño FPGA que definitivamente funcione en hardware real

9

Acabo de comenzar a aprender diseño de lógica digital con FPGA y he estado construyendo muchos proyectos. La mayoría de las veces (dado que soy un novato), tengo un diseño que simula perfectamente (simulación conductual) pero que no se sintetiza correctamente.

Entonces, mi pregunta es "¿cuáles son los pasos de diseño que puedo incorporar en mi flujo de trabajo, que garantizarán que tenga un diseño que funcione correctamente en mi FPGA?"

Tengo dos áreas principales en las que espero asesoramiento, pero esto se basa absolutamente en un punto de vista muy limitado como principiante, y más son bienvenidas:

  • ¿Qué todos los pasos (ver esquemas RTL, simulación post síntesis, ...) debo emprender aprendiendo para la mejor práctica?
  • Qué cosas debo tener en cuenta al diseñar mi lógica (digamos FSM o circuitos secuenciales) para evitar resultados inesperados.

Estoy usando un FPGA Xilinx Spartan 6 y el paquete de diseño Xilinx ISE para mi trabajo.

ironstein
fuente
1
¿Qué tipo de problemas te encuentras con la síntesis? ¿Logra un alto nivel de cobertura en la simulación?
pjc50
@ pjc50 No entiendo la pregunta. ¿Qué quiere decir "alto nivel de cobertura en simulación"?
ironstein
1
Tiene un banco de pruebas o estímulo que impulsa la simulación. Las herramientas de cobertura le indican qué porcentaje del diseño realmente está ejerciendo la prueba, como un porcentaje. Si este número es demasiado bajo, entonces su banco de pruebas es inadecuado y no está probando algunos casos que podrían surgir en el uso real.
pjc50
@ pjc50 que en realidad es un muy buen consejo. ¿Cuál es el equivalente de esto en la suite de diseño Xilinx ISE?
ironstein
1
Vale la pena señalar: sintetiza y "definitivamente funciona en hardware real" son diferentes niveles de rigor. Hay patrones que uno puede seguir para asegurarse de que sintetiza. Sin embargo, cuando se trata de hacerlo funcionar en hardware real, con certeza, uno debe recordar la máxima de la simulación: "Todos los modelos están equivocados; algunos son útiles".
Cort Ammon

Respuestas:

13

En un lugar donde trabajaba había dos campamentos de diseñadores de FPGA. Un campo que llamé simular, simular, simular o cubicado. El otro campamento era todo sobre diseño.

Los chicos cubicados usaron un simulador como modelsim, idearían un diseño inicial mediante métodos de codificación y / o bloques en la suite de diseño. Luego lo simularían y encontrarían las cosas que no funcionarían, luego cambiarían el código. Este proceso se repitió varias veces hasta que se les ocurrió un diseño que funcionó.

El campo de diseño (que preferí) diseñaría la forma de onda en papel (o papel digital como visio), exactamente lo que se requería. Luego inventa un diagrama lógico. Este es un proceso de autodocumentación. Luego, el diagrama se tradujo a código (el código y el diagrama eran 1: 1 si había algo en el diagrama, había un proceso para ello en el código). Luego se simuló, y la forma de onda de simulación se comparó con la forma de onda diseñada en papel, y se esperaba que fuera la misma.

Terminé haciendo ambas cosas, a veces entraba en el modo de cubos, y no fue muy divertido. Descubrí que a veces perdí de vista mi objetivo. Por ejemplo, cambiaría un estado en una máquina de estados, y el cambio se reduciría al siguiente estado, luego tendría que arreglar eso. Terminé pasando más tiempo que pensando en ello.

¿En qué campamento preferirías estar? Creo que debe haber un diseño riguroso, haga lo que funcione para usted, pero creo que cuanto más detallado y riguroso sea en el diseño, menos problemas tendrá a largo plazo. Di algunos ejemplos de lo que es posible, puede que no se ajusten a la estructura organizativa de su lugar de trabajo. La razón por la cual los detalles de diseño y la planificación cuidadosa son tan útiles es que te obliga a pensar en lo que estás haciendo. Facilita la depuración. Desarrolle un flujo de trabajo de diseño que permita que esto suceda. Además, familiarícese con las herramientas de simulación y escriba buenos bancos de pruebas que prueben todas las condiciones que pueda experimentar el dispositivo simulado. Por supuesto, esto debe equilibrarse con el tiempo. Por ejemplo, escriba el código ADC HDL que simulará el dispositivo en sus simulaciones.

La herramienta más valiosa para tener en el diseño de FPGA (en mi opinión) es un buen procedimiento de prueba que le permitirá probar completamente su diseño y ejecutarlo a su ritmo. No se puede esperar que un diseño de FPGA "simplemente funcione", se requiere un esfuerzo para asegurarse de que todas las piezas funcionen. Si detecta errores, vuelva a la simulación y el diseño y aprenda cuáles son las diferencias entre un FPGA simulado y RTL. Eso viene principalmente con la experiencia, pero si el diseño funciona en simulación pero no en hardware, entonces debe descubrir por qué hay una diferencia.

Algunas cosas clave que aprendí:
1) Desinfecte sus entradas, el reloj y los circuitos de reinicio deben estar limpios o puede obtener propagación de la metaestabilidad a través de su sistema. Sepa qué es un sincronizador de doble rango. Hay muchas topologías diferentes para restablecer circuitos, sepa cómo usarlos (hay un gran artículo en la web, aunque no lo tengo a mano).
2) Obtenga los requisitos del diseño por adelantado y luego diseñe en torno a ellos. Si las personas que te rodean no te darán requisitos definitivos, inventa algunos por tu cuenta.
3) La caja de herramientas de punto fijo de Matlab es excelente para simular sistemas de control y aplicaciones DSP, pero es posible que no tenga acceso a eso. Es una excelente manera de probar un diseño antes de codificar.
4) El diseño es lo primero, luego la codificación y luego la simulación.
5) Fuertemente tipado, también mantenga los nombres de señal consistentes en el esquema de pcb y hdl. (esta es también la razón por la que prefiero VHDL a verilog.

Pico de voltaje
fuente
2
+1 para "s en cubos" o syometrotulunatyoonorte3
Paebbels
Muy bien: al "diseño riguroso" agregaría "usando el sistema de tipos". Ejemplo: un índice de matriz del tipo apropiado, como el rango de la matriz, no es necesario probar la condición fuera de los límites. Solo estaría en desacuerdo con la "forma de onda en comparación con la forma de onda diseñada en papel" ... la forma de onda diseñada debería estar en VHDL para esa etapa (o tal vez leer del archivo de texto) y el simulador debería realizar la comparación.
Brian Drummond
También podría hacerse de esa manera, me pareció útil diseñar una forma de onda en papel porque daba algo con lo que comparar. Al igual que una forma de onda ADC, la sincronización se diseñó y luego se comparó con la salida de modlesim, luego se verificó físicamente. Si la salida de modelim es correcta, compárela con eso. El código fue fuertemente tipado (olvidé mencionar eso), pero eso es realmente importante. Es por eso que prefiero VHDL a verilog, hay menos atajos que puede tomar. Y hace que el código sea mucho más legible.
Voltaje pico el
si. En realidad, al igual que otras áreas como el software o el hardware convencional, el punto de partida es dividir el problema en bloques y luego preguntarse "cómo sabré cuándo funciona ese bloque". Entonces hacerlo. Construya su diseño bloque por bloque, luego junte los bloques y pruebe nuevamente que lo que obtiene es lo que se espera. A veces puede darse cuenta de que con un mejor diseño de nivel de bloque sería más limpio o más fácil, por lo que retrocede.
danmcb
6

Las cosas principales son:

  • Codificación cuidadosa para evitar estructuras no sintetizables.
  • Minimice los niveles lógicos para un mejor rendimiento de temporización (haga que la lógica entre registros sea lo más simple posible)
  • prueba, prueba, prueba para garantizar la corrección funcional y verificar cosas como registros no inicializados y cables desconectados
  • síntesis y verifique los registros de síntesis para ver si hay advertencias, asegúrese de que las advertencias no indiquen problemas (es decir, la advertencia de registro eliminado podría ser intencional (no utilizó una salida de módulo) o involuntaria (olvidó conectar la salida / error tipográfico / etc.))
  • mapeo y verifique el informe del mapa para las cifras de utilización, asegúrese de que el FPGA no esté demasiado lleno
  • análisis de lugar y ruta y sincronización, asegúrese de que su diseño se ejecutará a la velocidad de reloj requerida

He tenido varios diseños bastante complejos que funcionan correctamente (o al menos en su mayoría correctamente) en la primera prueba en un FPGA real siguiendo lo anterior. No es necesario verificar el esquema RTL, eso es extremadamente engorroso y una completa pérdida de tiempo para diseños grandes. Una simulación posterior a la síntesis sería mucho más útil.

alex.forencich
fuente
1
Gracias por su rápida respuesta. ¿Podría explicar el segundo punto (minimizar los niveles lógicos)?
ironstein
5

Todo su código sintetizable debe ser expresable como:

  • LUT
  • Chancletas
  • Primitivas específicas del proveedor

Las primitivas específicas del proveedor se instancian explícitamente, o son generadas por el asistente del proveedor, o inferidas por patrones de codificación muy específicos, por lo que no debería haber ninguna ambigüedad allí.

En VHDL, por ejemplo, no se puede usar wait foren código sintetizable. Para entender por qué, intente expresarse de manera determinista wait for 100 nsutilizando LUT o flip-flops. No puedes

Eso no significa que no pueda implementarlo configurando un contador con una frecuencia de reloj conocida (con un período que pueda dividir 100 ns) y use su cuenta para saber cuándo se acabó el tiempo. Pero el motor de síntesis no presentará este esquema automáticamente, debe ser explícito sobre la arquitectura en términos de lógica combinacional (puertas / LUT) y registros.

Entonces, lo principal a tener en cuenta para generar código sintetizable es tener una imagen relativamente clara de cómo su código se convierte en puertas lógicas y chanclas. Eso es realmente

apalopohapa
fuente
wait until rising_edge(clk);es sintetizable, aunque algunas herramientas imponen restricciones en su uso.
Brian Drummond
2

El primer paso más obvio es verificar las advertencias.

Las herramientas Xilinx producen archivos de registro que advierten sobre cualquier cosa que podría no ser lo que pretendía el codificador. A veces esto es molesto, cuando tienes montones de advertencias sobre señales no utilizadas que sabes perfectamente que no se usan. Pero a veces atrapa errores genuinos. Si eres un novato, las posibilidades de que cometas un error son significativamente mayores.

Entonces necesita configurar restricciones de tiempo. ¿Qué tan rápido después de un flanco ascendente en el reloj A necesita establecerse la línea de datos B? ¿O cuánto tiempo debe mantenerse la línea de datos B antes de un flanco descendente en el reloj A? Las restricciones de tiempo le permitirán especificar todo esto. Si no tiene restricciones de tiempo, el compilador puede suponer que no le importa particularmente y podría enrutar sus señales a cualquier parte. Si tiene restricciones de tiempo, el compilador trabajará para asegurarse de que sus señales cumplan con esas restricciones moviendo la ubicación. Y si no puede cumplir con las restricciones de tiempo, mostrará una advertencia.

Si su problema es que las salidas no están haciendo lo que espera, observe en detalle los bloques de E / S. Cada pin de E / S tiene un poco de lógica asociada y un flip-flop. Es posible que el orden en el que especifique las variables de estado y lógica en su código no permita que su código se ajuste a esta arquitectura, por lo que obtendrá un retraso adicional desde cualquier lugar donde se encuentre. Las advertencias sobre las restricciones de tiempo le dirán si esto sucede (suponiendo que haya configurado sus restricciones de tiempo), pero solucionarlo requiere que comprenda el hardware y cómo su diseño se correlacionará con el hardware. En general, esto es solo un problema cuando comienzas a alcanzar altas velocidades de reloj, pero vale la pena mencionarlo.

Graham
fuente