He estado diseñando algunos proyectos en diferentes FPGA en VHDL, y parece que mi fuente más común de "errores difíciles de encontrar" es cuando olvido sincronizar una señal asíncrona u olvido resincronizar una señal que cruza dominios de reloj.
Mi mejor arma hasta ahora ha sido dibujar esquemas de bloques de los componentes.
Entonces mi pregunta es, ¿cuál es la mejor práctica de diseño para evitar estos errores?
Hoy en día, incluso los diseños de FPGA pueden tener arquitecturas de reloj extremadamente complejas y muchas entradas asíncronas, lo que genera muchos problemas potenciales de CDC.
Diría que los siguientes puntos constituyen un conjunto mínimo de "reglas generales" para evitar errores de CDC:
Estoy seguro de que la lista anterior de prácticas está incompleta y puede ampliarse fácilmente.
También sugiero considerar las herramientas de verificación de CDC (como Questa CDC de Mentor): estas herramientas usan técnicas formales para detectar automáticamente problemas de CDC en su diseño.
Algunas prácticas de nomenclatura pueden ser útiles:
Cualquier señal que cruce un dominio de reloj debe tener adjunto el dominio con el que está sincronizada. Entonces, si tiene count
un dominio de reloj controlado por señal clk
(y necesita ir a otro dominio de reloj controlado por other_clk
), llámelo count_clk
y count_other_clk
.
Mantenga todo el código de sincronización de un dominio de reloj a otro en un solo lugar. Tal vez encapsularlo, dependiendo de cuánto haya. Ponga comentarios claros a su alrededor (por ejemplo, above here is clk
, this is the domain crossing from clk to other_clk
, below here is other_clk
)
Las señales verdaderamente asíncronas se pueden haber _async
agregado al final.
Esto al menos hace que la revisión de código sea un poco más fácil de manejar, pero si tiene muchos dominios y muchos cruces, le beneficiará invertir en algunas herramientas para ayudar (como Spyglass, por ejemplo, que hace mucho más que solo verificar dominios de reloj )
Además de las respuestas anteriores:
Use su herramienta de análisis de tiempo en su cadena de herramientas FPGA para encontrar cualquier señal que haya olvidado manejar correctamente.
Puede generar fácilmente una lista de transferencias de reloj sin restricciones, todas las cuales deben sincronizarse y agregarse una ruta falsa apropiada. Idealmente, incruste esto en su sistema de compilación para que falle con un error si hay transferencias de reloj sin restricciones, ¡entonces no puede olvidarse de ellas!
Tenga una sola entidad/módulo para realizar su sincronización de un solo bit, use un parámetro/genérico para controlar la cantidad de registros en la cadena de resincronización. Es posible que desee un sincronizador separado para reinicios.
La ventaja de reutilizar el código: incrustar las restricciones de ruta falsa en el RTL. De esa manera, no tiene que recordar agregar restricciones de tiempo para cada señal.
Los registros en las cadenas de sincronizadores deben colocarse juntos para garantizar que se proporcione la ventana de tiempo máxima. Altera afirma que detecta automáticamente las cadenas sincronizadoras, por lo que no deberían necesitar restricciones de ubicación. Si está paranoico con Xilinx, puede usar restricciones RLOC para asegurarse de que los registros de su sincronizador estén colocados juntos (desafortunadamente, Altera no admite restricciones de ubicación relativa).